• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.. All rights reserved.
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 #ifndef TEXTLINE_JUSTIFY_DEFINED
16 #define TEXTLINE_JUSTIFY_DEFINED
17 
18 #ifdef OHOS_SUPPORT
19 #include "include/core/SkScalar.h"
20 #include "modules/skparagraph/src/TextLine.h"
21 
22 namespace skia {
23 namespace textlayout {
24 
25 class TextLineJustify {
26 public:
TextLineJustify(TextLine & textLine)27     TextLineJustify(TextLine& textLine) : textLineRef(textLine) {}
28     bool justify(SkScalar maxWidth);
29 
30 private:
31     TextLine& textLineRef;
32 
33     struct HighLevelInfo {
34         ClusterIndex clusterIndex{SIZE_MAX};
35         bool isClusterPunct{false};
36         SkScalar punctWidths{0.0f};
37         SkScalar highLevelOffset{0.0f};
38     };
39 
40     struct MiddleLevelInfo {
41         ClusterIndex clusterIndex{SIZE_MAX};
42         bool isPrevClusterSpace{true};
43     };
44 
45     struct ClusterLevelsIndices {
46         std::vector<HighLevelInfo> highLevelIndices;
47         std::vector<MiddleLevelInfo> middleLevelIndices;
48         std::vector<ClusterIndex> LowLevelIndices;
49         SkScalar middleLevelOffset{0.0f};
50         SkScalar lowLevelOffset{0.0f};
51 
emptyClusterLevelsIndices52         bool empty()
53         {
54             return highLevelIndices.empty() && middleLevelIndices.empty() &&
55                    LowLevelIndices.empty();
56         }
57     };
58 
59     enum class ShiftLevel {
60         Undefined,
61         HighLevel,    // include: Punctuation
62         MiddleLevel,  // include: WhitespaceBreak, between ideographic and non-ideographic characters
63         LowLevel      // include: Between ideographic characters
64     };
65 
66     void allocateHighLevelOffsets(
67         SkScalar ideographicMaxLen, ClusterLevelsIndices& clusterLevels, SkScalar& allocatedWidth);
68     void allocateMiddleLevelOffsets(SkScalar ideographicMaxLen, size_t prevClusterNotSpaceCount,
69         ClusterLevelsIndices& clusterLevels, SkScalar& allocatedWidth);
70     void allocateLowLevelOffsets(
71         SkScalar ideographicMaxLen, ClusterLevelsIndices& clusterLevels, SkScalar& allocatedWidth);
72     void allocateRemainingWidth(
73         SkScalar allocatedWidth, size_t prevClusterNotSpaceCount, ClusterLevelsIndices& clusterLevels);
74     void distributeRemainingSpace(ClusterLevelsIndices& clusterLevels, SkScalar& middleLevelOffset,
75         SkScalar& lowLevelOffset, SkScalar& allocatedWidth);
76     SkScalar usingAutoSpaceWidth(const Cluster* cluster);
77     ShiftLevel determineShiftLevelForIdeographic(const Cluster* prevCluster, MiddleLevelInfo& middleLevelInfo);
78     ShiftLevel determineShiftLevelForPunctuation(
79         const Cluster* cluster, const Cluster* prevCluster, HighLevelInfo& highLevelInfo);
80     ShiftLevel determineShiftLevelForWhitespaceBreak(const Cluster* prevCluster);
81     ShiftLevel determineShiftLevelForOtherCases(const Cluster* prevCluster, MiddleLevelInfo& middleLevelInfo);
82     ShiftLevel determineShiftLevel(const Cluster* cluster, const Cluster* prevCluster, HighLevelInfo& highLevelInfo,
83         MiddleLevelInfo& middleLevelInfo, SkScalar& ideographicMaxLen);
84     SkScalar calculateClusterShift(
85         const Cluster* cluster, ClusterIndex index, const ClusterLevelsIndices& clusterLevels);
86     void justifyShiftCluster(const SkScalar maxWidth, SkScalar textLen, SkScalar ideographicMaxLen,
87         size_t prevClusterNotSpaceCount, ClusterLevelsIndices& clusterLevels);
88 };
89 }  // namespace textlayout
90 }  // namespace skia
91 
92 #endif  // OHOS_SUPPORT
93 #endif  // TEXTLINE_JUSTIFY_DEFINED