Bumping manifests a=b2g-bump
[gecko.git] / layout / generic / JustificationUtils.h
blob129ad0b6e1f5b570297c19deaa228be3873c0747
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_JustificationUtils_h_
8 #define mozilla_JustificationUtils_h_
10 #include "mozilla/Attributes.h"
12 namespace mozilla {
14 /**
15 * Jutification Algorithm
17 * The justification algorithm is based on expansion opportunities
18 * between justifiable clusters. By this algorithm, there is one
19 * expansion opportunity at each side of a justifiable cluster, and
20 * at most one opportunity between two clusters. For example, if there
21 * is a line in a Chinese document is: "你好世界hello world", then
22 * the expansion opportunities (marked as '*') would be:
24 * 你*好*世*界*hello*' '*world
26 * The spacing left in a line will then be distributed equally to each
27 * opportunities. Because we want that, only justifiable clusters get
28 * expanded, and the split point between two justifiable clusters would
29 * be at the middle of the spacing, each expansion opportunities will be
30 * filled by two justification gaps. The example above would be:
32 * 你 | 好 | 世 | 界 |hello| ' ' |world
34 * In the algorithm, information about expansion opportunities is stored
35 * in structure JustificationInfo, and the assignment of justification
36 * gaps is in structure JustificationAssignment.
39 struct JustificationInfo
41 // Number of expansion opportunities inside a span. It doesn't include
42 // any opportunities between this span and the one before or after.
43 int32_t mInnerOpportunities;
44 // The justifiability of the start and end sides of the span.
45 bool mIsStartJustifiable;
46 bool mIsEndJustifiable;
48 MOZ_CONSTEXPR JustificationInfo()
49 : mInnerOpportunities(0)
50 , mIsStartJustifiable(false)
51 , mIsEndJustifiable(false)
55 // Claim that the last opportunity should be cancelled
56 // because the trailing space just gets trimmed.
57 void CancelOpportunityForTrimmedSpace()
59 if (mInnerOpportunities > 0) {
60 mInnerOpportunities--;
61 } else {
62 // There is no inner opportunities, hence the whole frame must
63 // contain only the trimmed space, because any content before
64 // space would cause an inner opportunity. The space made each
65 // side justifiable, which should be cancelled now.
66 mIsStartJustifiable = false;
67 mIsEndJustifiable = false;
72 struct JustificationAssignment
74 // There are at most 2 gaps per end, so it is enough to use 2 bits.
75 uint8_t mGapsAtStart : 2;
76 uint8_t mGapsAtEnd : 2;
78 MOZ_CONSTEXPR JustificationAssignment()
79 : mGapsAtStart(0)
80 , mGapsAtEnd(0)
84 int32_t TotalGaps() const { return mGapsAtStart + mGapsAtEnd; }
87 struct JustificationApplicationState
89 struct
91 // The total number of justification gaps to be processed.
92 int32_t mCount;
93 // The number of justification gaps which have been handled.
94 int32_t mHandled;
95 } mGaps;
97 struct
99 // The total spacing left in a line before justification.
100 nscoord mAvailable;
101 // The spacing has been consumed by handled justification gaps.
102 nscoord mConsumed;
103 } mWidth;
105 JustificationApplicationState(int32_t aGaps, nscoord aWidth)
107 mGaps.mCount = aGaps;
108 mGaps.mHandled = 0;
109 mWidth.mAvailable = aWidth;
110 mWidth.mConsumed = 0;
113 bool IsJustifiable() const
115 return mGaps.mCount > 0 && mWidth.mAvailable > 0;
118 nscoord Consume(int32_t aGaps)
120 mGaps.mHandled += aGaps;
121 nscoord newAllocate = (mWidth.mAvailable * mGaps.mHandled) / mGaps.mCount;
122 nscoord deltaWidth = newAllocate - mWidth.mConsumed;
123 mWidth.mConsumed = newAllocate;
124 return deltaWidth;
128 class JustificationUtils
130 public:
131 // Compute justification gaps should be applied on a unit.
132 static int32_t CountGaps(const JustificationInfo& aInfo,
133 const JustificationAssignment& aAssign)
135 // Justification gaps include two gaps for each inner opportunities
136 // and the gaps given assigned to the ends.
137 return aInfo.mInnerOpportunities * 2 + aAssign.TotalGaps();
143 #endif /* !defined(mozilla_JustificationUtils_h_) */