1// Copyright 2019 Google LLC.
2#ifndef ParagraphStyle_DEFINED
3#define ParagraphStyle_DEFINED
4
5#include "include/core/SkFontStyle.h"
6#include "include/core/SkScalar.h"
7#include "include/core/SkString.h"
8#include "modules/skparagraph/include/DartTypes.h"
9#include "modules/skparagraph/include/TextStyle.h"
10#include "drawing.h"
11
12#include <stddef.h>
13#include <algorithm>
14#include <limits>
15#include <string>
16#include <utility>
17#include <vector>
18
19namespace skia {
20namespace textlayout {
21
22#ifdef OHOS_SUPPORT
23struct TextTabs {
24    TextAlign alignment;
25    SkScalar location;
26    bool operator==(const TextTabs& other) const {
27        return (alignment == other.alignment) && nearlyEqual(location, other.location);
28    }
29};
30#endif
31
32enum class WordBreakType {
33    NORMAL,     // to be done.
34    BREAK_ALL,  // break occur after any characters.
35    BREAK_WORD, // break only occur after word.
36};
37
38enum class LineBreakStrategy {
39    GREEDY,        // faster and linear.
40    HIGH_QUALITY,  // breaking tries to split the lines as efficiently as possible
41    BALANCED,      // breaking tries to make the line lengths even
42};
43
44struct StrutStyle {
45    StrutStyle();
46
47    const std::vector<SkString>& getFontFamilies() const { return fFontFamilies; }
48    void setFontFamilies(std::vector<SkString> families) { fFontFamilies = std::move(families); }
49
50#ifndef USE_SKIA_TXT
51    SkFontStyle getFontStyle() const { return fFontStyle; }
52    void setFontStyle(SkFontStyle fontStyle) { fFontStyle = fontStyle; }
53#else
54    RSFontStyle getFontStyle() const { return fFontStyle; }
55    void setFontStyle(RSFontStyle fontStyle) { fFontStyle = fontStyle; }
56#endif
57
58    SkScalar getFontSize() const { return fFontSize; }
59    void setFontSize(SkScalar size) { fFontSize = size; }
60
61    void setHeight(SkScalar height) { fHeight = height; }
62    SkScalar getHeight() const { return fHeight; }
63
64    void setLeading(SkScalar Leading) { fLeading = Leading; }
65    SkScalar getLeading() const { return fLeading; }
66
67    bool getStrutEnabled() const { return fEnabled; }
68    void setStrutEnabled(bool v) { fEnabled = v; }
69
70    bool getForceStrutHeight() const { return fForceHeight; }
71    void setForceStrutHeight(bool v) { fForceHeight = v; }
72
73    bool getHeightOverride() const { return fHeightOverride; }
74    void setHeightOverride(bool v) { fHeightOverride = v; }
75
76    void setHalfLeading(bool halfLeading) { fHalfLeading = halfLeading; }
77    bool getHalfLeading() const { return fHalfLeading; }
78
79    void setWordBreakType(const WordBreakType& wordBreakType) { fWordBreakType = wordBreakType; }
80    WordBreakType getWordBreakType() const { return fWordBreakType; }
81
82    void setLineBreakStrategy(const LineBreakStrategy& lineBreakStrategy) { fLineBreakStrategy = lineBreakStrategy; }
83    LineBreakStrategy getLineBreakStrategy() const { return fLineBreakStrategy; }
84
85    bool operator==(const StrutStyle& rhs) const {
86        return this->fEnabled == rhs.fEnabled &&
87               this->fHeightOverride == rhs.fHeightOverride &&
88               this->fForceHeight == rhs.fForceHeight &&
89               this->fHalfLeading == rhs.fHalfLeading &&
90               nearlyEqual(this->fLeading, rhs.fLeading) &&
91               nearlyEqual(this->fHeight, rhs.fHeight) &&
92               nearlyEqual(this->fFontSize, rhs.fFontSize) &&
93               this->fFontStyle == rhs.fFontStyle &&
94               this->fFontFamilies == rhs.fFontFamilies &&
95               this->fWordBreakType == rhs.fWordBreakType &&
96               this->fLineBreakStrategy == rhs.fLineBreakStrategy;
97    }
98
99private:
100
101    std::vector<SkString> fFontFamilies;
102#ifndef USE_SKIA_TXT
103    SkFontStyle fFontStyle;
104#else
105    RSFontStyle fFontStyle;
106#endif
107    SkScalar fFontSize;
108    SkScalar fHeight;
109    SkScalar fLeading;
110    bool fForceHeight;
111    bool fEnabled;
112    bool fHeightOverride;
113    // true: half leading.
114    // false: scale ascent/descent with fHeight.
115    bool fHalfLeading;
116    WordBreakType fWordBreakType;
117    LineBreakStrategy fLineBreakStrategy { LineBreakStrategy::GREEDY };
118};
119
120struct ParagraphStyle {
121    ParagraphStyle();
122
123    bool operator==(const ParagraphStyle& rhs) const {
124        return this->fHeight == rhs.fHeight &&
125               this->fEllipsis == rhs.fEllipsis &&
126               this->fEllipsisUtf16 == rhs.fEllipsisUtf16 &&
127               this->fTextDirection == rhs.fTextDirection && this->fTextAlign == rhs.fTextAlign &&
128               this->fDefaultTextStyle == rhs.fDefaultTextStyle &&
129               this->fEllipsisModal == rhs.fEllipsisModal &&
130               this->fTextOverflower == rhs.fTextOverflower &&
131               this->fReplaceTabCharacters == rhs.fReplaceTabCharacters &&
132#ifdef OHOS_SUPPORT
133               this->fTextTab == rhs.fTextTab &&
134#endif
135               nearlyEqual(this->fTextSplitRatio, rhs.fTextSplitRatio);
136    }
137
138    const StrutStyle& getStrutStyle() const { return fStrutStyle; }
139    void setStrutStyle(StrutStyle strutStyle) { fStrutStyle = std::move(strutStyle); }
140
141    const TextStyle& getTextStyle() const { return fDefaultTextStyle; }
142    void setTextStyle(const TextStyle& textStyle) { fDefaultTextStyle = textStyle; }
143
144    TextDirection getTextDirection() const { return fTextDirection; }
145    void setTextDirection(TextDirection direction) { fTextDirection = direction; }
146
147    TextAlign getTextAlign() const { return fTextAlign; }
148    void setTextAlign(TextAlign align) { fTextAlign = align; }
149
150    size_t getMaxLines() const { return fLinesLimit; }
151    void setMaxLines(size_t maxLines) { fLinesLimit = maxLines; }
152
153    SkString getEllipsis() const { return fEllipsis; }
154    std::u16string getEllipsisUtf16() const { return fEllipsisUtf16; }
155    void setEllipsis(const std::u16string& ellipsis) {  fEllipsisUtf16 = ellipsis; }
156    void setEllipsis(const SkString& ellipsis) { fEllipsis = ellipsis; }
157
158    SkScalar getHeight() const { return fHeight; }
159    void setHeight(SkScalar height) { fHeight = height; }
160
161    TextHeightBehavior getTextHeightBehavior() const { return fTextHeightBehavior; }
162    void setTextHeightBehavior(TextHeightBehavior v) { fTextHeightBehavior = v; }
163
164    bool unlimited_lines() const {
165        return fLinesLimit == std::numeric_limits<size_t>::max();
166    }
167    bool ellipsized() const { return !fEllipsis.isEmpty() || !fEllipsisUtf16.empty(); }
168    TextAlign effective_align() const;
169    bool hintingIsOn() const { return fHintingIsOn; }
170    void turnHintingOff() { fHintingIsOn = false; }
171
172    bool getReplaceTabCharacters() const { return fReplaceTabCharacters; }
173    void setReplaceTabCharacters(bool value) { fReplaceTabCharacters = value; }
174
175    skia::textlayout::EllipsisModal getEllipsisMod() const { return fEllipsisModal; }
176    void setEllipsisMod(skia::textlayout::EllipsisModal ellipsisModel) { fEllipsisModal = ellipsisModel; }
177    SkScalar getTextSplitRatio() const { return fTextSplitRatio; }
178    void setTextSplitRatio(SkScalar textSplitRatio) { fTextSplitRatio = textSplitRatio; }
179
180    bool getTextOverflower() const { return fTextOverflower; }
181    void setTextOverflower(bool textOverflowerFlag) { fTextOverflower = textOverflowerFlag; }
182
183#ifdef OHOS_SUPPORT
184    const TextTabs& getTextTab() const { return fTextTab; }
185    void setTextTab(const TextTabs& textTab) { fTextTab = textTab; }
186#endif
187private:
188    StrutStyle fStrutStyle;
189    TextStyle fDefaultTextStyle;
190    TextAlign fTextAlign;
191    TextDirection fTextDirection;
192    size_t fLinesLimit;
193    std::u16string fEllipsisUtf16;
194    SkString fEllipsis;
195    SkScalar fHeight;
196    TextHeightBehavior fTextHeightBehavior;
197    bool fHintingIsOn;
198    bool fReplaceTabCharacters;
199    bool fTextOverflower;
200    skia::textlayout::EllipsisModal fEllipsisModal;
201    SkScalar fTextSplitRatio = 0.5f;
202#ifdef OHOS_SUPPORT
203    TextTabs fTextTab;
204#endif
205};
206}  // namespace textlayout
207}  // namespace skia
208
209#endif  // ParagraphStyle_DEFINED
210