1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_SVG_PAINT_STATE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_SVG_PAINT_STATE_H 18 19 #include "base/memory/ace_type.h" 20 #include "core/components/common/properties/animatable_double.h" 21 #include "frameworks/core/components/common/layout/constants.h" 22 #include "frameworks/core/components/common/properties/color.h" 23 #include "frameworks/core/components/common/properties/decoration.h" 24 #include "frameworks/core/components/common/properties/paint_state.h" 25 #include "frameworks/core/components/common/properties/text_style.h" 26 27 namespace OHOS::Ace { 28 29 const char ATTR_NAME_FILL[] = "fill"; 30 const char ATTR_NAME_STROKE[] = "stroke"; 31 const char ATTR_NAME_STROKE_WIDTH[] = "stroke-width"; 32 const char ATTR_NAME_MITER_LIMIT[] = "stroke-miterlimit"; 33 const char ATTR_NAME_STROKE_DASH_OFFSET[] = "stroke-dashoffset"; 34 const char ATTR_NAME_FONT_SIZE[] = "font-size"; 35 const char ATTR_NAME_FILL_OPACITY[] = "fill-opacity"; 36 const char ATTR_NAME_STROKE_OPACITY[] = "stroke-opacity"; 37 const char ATTR_NAME_LETTER_SPACING[] = "letter-spacing"; 38 const char ANIMATOR_TYPE_MOTION[] = "motion"; 39 const char ATTR_NAME_FILL_RULE_EVENODD[] = "evenodd"; 40 41 class FillState { 42 public: SetContextAndCallback(const WeakPtr<PipelineContext> & context,const RenderNodeAnimationCallback & callback)43 void SetContextAndCallback(const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback) 44 { 45 color_.SetContextAndCallback(context, callback); 46 opacity_.SetContextAndCallback(context, callback); 47 } 48 GetColor()49 const AnimatableColor& GetColor() const 50 { 51 return color_; 52 } 53 54 /** 55 * set fill color 56 * @param color 57 * @param isSelf if false the color value inherited from the parent node, otherwise the value is setted by self 58 */ 59 void SetColor(const Color& color, bool isSelf = true, const AnimationOption& option = AnimationOption()) 60 { 61 color_ = AnimatableColor(color, option); 62 hasColor_ = isSelf; 63 } 64 GetGradient()65 std::optional<Gradient>& GetGradient() 66 { 67 return gradient_; 68 } 69 GetGradient()70 const std::optional<Gradient>& GetGradient() const 71 { 72 return gradient_; 73 } 74 75 void SetGradient(const Gradient& gradient, bool isSelf = true) 76 { 77 gradient_ = std::make_optional(gradient); 78 hasGradient_ = isSelf; 79 } 80 81 void SetOpacity(double opacity, bool isSelf = true, const AnimationOption& option = AnimationOption()) 82 { 83 opacity_ = AnimatableDouble(opacity, option); 84 hasOpacity_ = isSelf; 85 } 86 GetOpacity()87 AnimatableDouble GetOpacity() const 88 { 89 return opacity_; 90 } 91 92 void SetFillRule(const std::string& fillRule, bool isSelf = true) 93 { 94 fillRule_ = fillRule; 95 hasFillRule_ = isSelf; 96 } 97 GetFillRule()98 const std::string& GetFillRule() const 99 { 100 return fillRule_; 101 } 102 IsEvenodd()103 bool IsEvenodd() const 104 { 105 return fillRule_ == ATTR_NAME_FILL_RULE_EVENODD; 106 } 107 Inherit(const FillState & parent)108 void Inherit(const FillState& parent) 109 { 110 if (!hasColor_) { 111 color_ = parent.GetColor(); 112 } 113 if (!hasOpacity_) { 114 opacity_ = parent.GetOpacity(); 115 } 116 if (!hasFillRule_) { 117 fillRule_ = parent.GetFillRule(); 118 } 119 if (!hasGradient_) { 120 gradient_ = parent.GetGradient(); 121 } 122 } 123 HasColor()124 bool HasColor() const 125 { 126 return hasColor_; 127 } 128 HasOpacity()129 bool HasOpacity() const 130 { 131 return hasOpacity_; 132 } 133 SetHref(const std::string & href)134 void SetHref(const std::string& href) 135 { 136 href_ = href; 137 } 138 GetHref()139 const std::string& GetHref() const 140 { 141 return href_; 142 } 143 144 protected: 145 AnimatableColor color_ = AnimatableColor(Color::BLACK); 146 AnimatableDouble opacity_ = AnimatableDouble(1.0); 147 std::string fillRule_; 148 std::optional<Gradient> gradient_; 149 bool hasColor_ = false; 150 bool hasOpacity_ = false; 151 bool hasFillRule_ = false; 152 bool hasGradient_ = false; 153 std::string href_; 154 }; 155 156 class StrokeState { 157 public: SetContextAndCallback(const WeakPtr<PipelineContext> & context,const RenderNodeAnimationCallback & callback)158 void SetContextAndCallback(const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback) 159 { 160 lineWidth_.SetContextAndCallback(context, callback); 161 color_.SetContextAndCallback(context, callback); 162 opacity_.SetContextAndCallback(context, callback); 163 strokeDashOffset_.SetContextAndCallback(context, callback); 164 } 165 GetColor()166 const AnimatableColor& GetColor() const 167 { 168 return color_; 169 } 170 171 void SetColor(const Color& color, bool isSelf = true, const AnimationOption& option = AnimationOption()) 172 { 173 color_ = AnimatableColor(color, option); 174 hasColor_ = isSelf; 175 } 176 177 void SetOpacity(double opacity, bool isSelf = true, const AnimationOption& option = AnimationOption()) 178 { 179 opacity_ = AnimatableDouble(opacity, option); 180 hasOpacity_ = isSelf; 181 } 182 GetOpacity()183 AnimatableDouble GetOpacity() const 184 { 185 return opacity_; 186 } 187 GetLineCap()188 LineCapStyle GetLineCap() const 189 { 190 return lineCap_; 191 } 192 193 void SetLineCap(LineCapStyle lineCap, bool isSelf = true) 194 { 195 lineCap_ = lineCap; 196 hasLineCap_ = isSelf; 197 } 198 GetLineJoin()199 LineJoinStyle GetLineJoin() const 200 { 201 return lineJoin_; 202 } 203 204 void SetLineJoin(LineJoinStyle lineJoin, bool isSelf = true) 205 { 206 lineJoin_ = lineJoin; 207 hasLineJoin_ = isSelf; 208 } 209 GetLineWidth()210 const AnimatableDimension& GetLineWidth() const 211 { 212 return lineWidth_; 213 } 214 215 void SetLineWidth(Dimension lineWidth, bool isSelf = true, const AnimationOption& option = AnimationOption()) 216 { 217 lineWidth_ = AnimatableDimension(lineWidth, option); 218 hasLineWidth_ = isSelf; 219 } 220 GetMiterLimit()221 double GetMiterLimit() const 222 { 223 return miterLimit_; 224 } 225 226 void SetMiterLimit(double miterLimit, bool isSelf = true) 227 { 228 miterLimit_ = miterLimit; 229 hasMiterLimit_ = isSelf; 230 } 231 GetLineDash()232 const LineDashParam& GetLineDash() const 233 { 234 return lineDash_; 235 } 236 237 void SetLineDash(const LineDashParam& lineDash, bool isSelf = true) 238 { 239 lineDash_ = lineDash; 240 hasLineDash_ = isSelf; 241 } 242 243 void SetLineDashOffset(double offset, bool isSelf = true) 244 { 245 lineDash_.dashOffset = offset; 246 hasDashOffset_ = isSelf; 247 } 248 249 void SetLineDash(const std::vector<double>& segments, bool isSelf = true) 250 { 251 lineDash_.lineDash = segments; 252 hasLineDash_ = isSelf; 253 } 254 255 void SetStrokeDashOffset(const Dimension& offset, bool isSelf = true, 256 const AnimationOption& option = AnimationOption()) 257 { 258 strokeDashOffset_ = AnimatableDimension(offset, option); 259 hasStrokeDashOffset_ = isSelf; 260 } 261 262 void SetStrokeDashArray(const std::vector<Dimension>& segments, bool isSelf = true) 263 { 264 strokeDashArray_ = segments; 265 hasStrokeDashArray_ = isSelf; 266 } 267 GetStrokeDashOffset()268 const AnimatableDimension& GetStrokeDashOffset() const 269 { 270 return strokeDashOffset_; 271 } 272 GetStrokeDashArray()273 const std::vector<Dimension>& GetStrokeDashArray() const 274 { 275 return strokeDashArray_; 276 } 277 HasStroke()278 bool HasStroke() const 279 { 280 // The text outline is drawn only when stroke is set 281 return color_ != Color::TRANSPARENT; 282 } 283 Inherit(const StrokeState & strokeState)284 void Inherit(const StrokeState& strokeState) 285 { 286 if (!hasColor_) { 287 color_ = strokeState.GetColor(); 288 } 289 if (!hasOpacity_) { 290 opacity_ = strokeState.GetOpacity(); 291 } 292 if (!hasLineCap_) { 293 lineCap_ = strokeState.GetLineCap(); 294 } 295 if (!hasLineJoin_) { 296 lineJoin_ = strokeState.GetLineJoin(); 297 } 298 if (!hasLineWidth_) { 299 lineWidth_ = strokeState.GetLineWidth(); 300 } 301 if (!hasMiterLimit_) { 302 miterLimit_ = strokeState.GetMiterLimit(); 303 } 304 if (!hasLineDash_) { 305 lineDash_.lineDash = strokeState.GetLineDash().lineDash; 306 } 307 if (!hasDashOffset_) { 308 lineDash_.dashOffset = strokeState.GetLineDash().dashOffset; 309 } 310 if (!hasStrokeDashArray_) { 311 strokeDashArray_ = strokeState.GetStrokeDashArray(); 312 } 313 if (!hasStrokeDashOffset_) { 314 strokeDashOffset_ = strokeState.GetStrokeDashOffset(); 315 } 316 if (!hasGradient_) { 317 gradient_ = strokeState.GetGradient(); 318 } 319 } 320 GetGradient()321 std::optional<Gradient>& GetGradient() 322 { 323 return gradient_; 324 } 325 GetGradient()326 const std::optional<Gradient>& GetGradient() const 327 { 328 return gradient_; 329 } 330 331 void SetGradient(const Gradient& gradient, bool isSelf = true) 332 { 333 gradient_ = std::make_optional(gradient); 334 hasGradient_ = isSelf; 335 } 336 HasColor()337 bool HasColor() const 338 { 339 return hasColor_; 340 } 341 HasOpacity()342 bool HasOpacity() const 343 { 344 return hasOpacity_; 345 } 346 HasLineWidth()347 bool HasLineWidth() const 348 { 349 return hasLineWidth_; 350 } 351 HasMiterLimit()352 bool HasMiterLimit() const 353 { 354 return hasMiterLimit_; 355 } 356 HasDashOffset()357 bool HasDashOffset() const 358 { 359 return hasDashOffset_; 360 } 361 SetHref(const std::string & href)362 void SetHref(const std::string& href) 363 { 364 href_ = href; 365 } 366 GetHref()367 const std::string& GetHref() const 368 { 369 return href_; 370 } 371 372 private: 373 AnimatableColor color_ = AnimatableColor(Color::TRANSPARENT); 374 AnimatableDouble opacity_ = AnimatableDouble(1.0); 375 LineCapStyle lineCap_ = LineCapStyle::BUTT; 376 LineJoinStyle lineJoin_ = LineJoinStyle::MITER; 377 AnimatableDimension lineWidth_ = AnimatableDimension(1.0); 378 double miterLimit_ = 4.0; 379 LineDashParam lineDash_; 380 std::vector<Dimension> strokeDashArray_; 381 AnimatableDimension strokeDashOffset_; 382 std::optional<Gradient> gradient_; 383 std::string href_; 384 bool hasColor_ = false; 385 bool hasOpacity_ = false; 386 bool hasLineCap_ = false; 387 bool hasLineJoin_ = false; 388 bool hasLineWidth_ = false; 389 bool hasMiterLimit_ = false; 390 bool hasLineDash_ = false; 391 bool hasDashOffset_ = false; 392 bool hasStrokeDashArray_ = false; 393 bool hasStrokeDashOffset_ = false; 394 bool hasGradient_ = false; 395 }; 396 397 class SvgTextStyle { 398 public: 399 void SetFontFamilies(const std::vector<std::string>& fontFamilies, bool isSelf = true) 400 { 401 hasFontFamilies_ = isSelf; 402 textStyle_.SetFontFamilies(fontFamilies); 403 } 404 GetFontFamilies()405 const std::vector<std::string>& GetFontFamilies() const 406 { 407 return textStyle_.GetFontFamilies(); 408 } 409 410 void SetFontSize(const Dimension& fontSize, bool isSelf = true) 411 { 412 textStyle_.SetFontSize(fontSize); 413 hasFontSize_ = isSelf; 414 } 415 GetFontSize()416 const Dimension& GetFontSize() const 417 { 418 return textStyle_.GetFontSize(); 419 } 420 421 void SetFontStyle(FontStyle fontStyle, bool isSelf = true) 422 { 423 textStyle_.SetFontStyle(fontStyle); 424 hasFontStyle_ = isSelf; 425 } 426 GetFontStyle()427 FontStyle GetFontStyle() const 428 { 429 return textStyle_.GetFontStyle(); 430 } 431 432 void SetFontWeight(FontWeight fontWeight, bool isSelf = true) 433 { 434 textStyle_.SetFontWeight(fontWeight); 435 hasFontWeight_ = isSelf; 436 } 437 GetFontWeight()438 FontWeight GetFontWeight() const 439 { 440 return textStyle_.GetFontWeight(); 441 } 442 443 void SetLetterSpacing(const Dimension& letterSpacing, bool isSelf = true) 444 { 445 textStyle_.SetLetterSpacing(letterSpacing); 446 hasLetterSpacing_ = isSelf; 447 } 448 GetLetterSpacing()449 const Dimension& GetLetterSpacing() const 450 { 451 return textStyle_.GetLetterSpacing(); 452 } 453 454 void SetTextDecoration(TextDecoration textDecoration, bool isSelf = true) 455 { 456 textStyle_.SetTextDecoration(textDecoration); 457 hasTextDecoration_ = isSelf; 458 } 459 GetTextDecoration()460 TextDecoration GetTextDecoration() const 461 { 462 return textStyle_.GetTextDecoration(); 463 } 464 GetTextStyle()465 const TextStyle& GetTextStyle() const 466 { 467 return textStyle_; 468 } 469 Inherit(const SvgTextStyle & parent)470 void Inherit(const SvgTextStyle& parent) 471 { 472 if (!hasFontFamilies_) { 473 textStyle_.SetFontFamilies(parent.GetFontFamilies()); 474 } 475 if (!hasFontSize_) { 476 textStyle_.SetFontSize(parent.GetFontSize()); 477 } 478 if (!hasFontStyle_) { 479 textStyle_.SetFontStyle(parent.GetFontStyle()); 480 } 481 if (!hasFontWeight_) { 482 textStyle_.SetFontWeight(parent.GetFontWeight()); 483 } 484 if (!hasLetterSpacing_) { 485 textStyle_.SetLetterSpacing(parent.GetLetterSpacing()); 486 } 487 if (!hasTextDecoration_) { 488 textStyle_.SetTextDecoration(parent.GetTextDecoration()); 489 } 490 } 491 HasLetterSpacing()492 bool HasLetterSpacing() const 493 { 494 return hasLetterSpacing_; 495 } 496 HasFontSize()497 bool HasFontSize() const 498 { 499 return hasFontSize_; 500 } 501 502 private: 503 TextStyle textStyle_; 504 bool hasFontFamilies_ = false; 505 bool hasFontSize_ = false; 506 bool hasFontStyle_ = false; 507 bool hasFontWeight_ = false; 508 bool hasLetterSpacing_ = false; 509 bool hasTextDecoration_ = false; 510 }; 511 512 class ClipState { 513 public: 514 void SetClipRule(const std::string& clipRule, bool isSelf = true) 515 { 516 clipRule_ = clipRule; 517 hasClipRule_ = isSelf; 518 } 519 GetClipRule()520 const std::string& GetClipRule() const 521 { 522 return clipRule_; 523 } 524 IsEvenodd()525 bool IsEvenodd() const 526 { 527 return clipRule_ == ATTR_NAME_FILL_RULE_EVENODD; 528 } 529 530 void SetHref(const std::string& href, bool isSelf = true) 531 { 532 href_ = href; 533 hasHref_ = isSelf; 534 } 535 GetHref()536 const std::string& GetHref() const 537 { 538 return href_; 539 } 540 Inherit(const ClipState & clipState)541 void Inherit(const ClipState& clipState) 542 { 543 if (!hasClipRule_) { 544 clipRule_ = clipState.GetClipRule(); 545 } 546 if (!hasHref_) { 547 href_ = clipState.GetHref(); 548 } 549 } 550 551 private: 552 std::string clipRule_; 553 std::string href_; 554 bool hasClipRule_ = false; 555 bool hasHref_ = false; 556 }; 557 558 } // namespace OHOS::Ace 559 560 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_SVG_PAINT_STATE_H 561