• 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 <unordered_set>
20 #include "include/core/SkScalar.h"
21 #include "modules/skparagraph/src/TextLine.h"
22 
23 namespace skia {
24 namespace textlayout {
25 
26 class TextLineJustify {
27 public:
TextLineJustify(TextLine & textLine)28     TextLineJustify(TextLine& textLine) : textLineRef(textLine) {}
29     bool justify(SkScalar maxWidth);
30 
31 private:
32     TextLine& textLineRef;
33 
34     struct HighLevelInfo {
35         ClusterIndex clusterIndex{SIZE_MAX};
36         bool isClusterPunct{false};
37         SkScalar punctWidths{0.0f};
38         SkScalar highLevelOffset{0.0f};
39     };
40 
41     struct MiddleLevelInfo {
42         ClusterIndex clusterIndex{SIZE_MAX};
43         bool isPrevClusterSpace{true};
44     };
45 
46     struct ClusterLevelsIndices {
47         std::map<ClusterIndex, HighLevelInfo> highLevelIndices;
48         std::unordered_map<ClusterIndex, MiddleLevelInfo> middleLevelIndices;
49         std::unordered_set<ClusterIndex> LowLevelIndices;
50         SkScalar middleLevelOffset{0.0f};
51         SkScalar lowLevelOffset{0.0f};
52 
emptyClusterLevelsIndices53         bool empty()
54         {
55             return highLevelIndices.empty() && middleLevelIndices.empty() &&
56                    LowLevelIndices.empty();
57         }
58     };
59 
60     enum class ShiftLevel {
61         Undefined,
62         HighLevel,    // include: Punctuation
63         MiddleLevel,  // include: WhitespaceBreak, between ideographic and non-ideographic characters
64         LowLevel      // include: Between ideographic characters
65     };
66 
67     void allocateHighLevelOffsets(
68         SkScalar ideographicMaxLen, ClusterLevelsIndices& clusterLevels, SkScalar& allocatedWidth);
69     void allocateMiddleLevelOffsets(SkScalar ideographicMaxLen, size_t prevClusterNotSpaceCount,
70         ClusterLevelsIndices& clusterLevels, SkScalar& allocatedWidth);
71     void allocateLowLevelOffsets(
72         SkScalar ideographicMaxLen, ClusterLevelsIndices& clusterLevels, SkScalar& allocatedWidth);
73     void allocateRemainingWidth(
74         SkScalar allocatedWidth, size_t prevClusterNotSpaceCount, ClusterLevelsIndices& clusterLevels);
75     void distributeRemainingSpace(ClusterLevelsIndices& clusterLevels, SkScalar& middleLevelOffset,
76         SkScalar& lowLevelOffset, SkScalar& allocatedWidth);
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