Skip to content

Commit 780ba56

Browse files
authored
Merge pull request #817 from ad619659/design_refactorings
Design refactoring for CounterFunction/FSLinearGradient
2 parents 9ea759c + ab156f6 commit 780ba56

6 files changed

Lines changed: 146 additions & 142 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.openhtmltopdf.context;
2+
3+
import com.openhtmltopdf.css.extend.ContentFunction;
4+
5+
public abstract class ContentFunctionAbstract implements ContentFunction {
6+
public boolean isStatic() {
7+
return false;
8+
};
9+
}

openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/ContentFunctionFactory.java

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,7 @@ public void registerFunction(ContentFunction function) {
6767
* Example:
6868
* <code>content: "Page " counter(page) -fs-if-cut-off(" continued") " of " counter(pages);</code>
6969
*/
70-
private static class FsIfCutOffFunction implements ContentFunction {
71-
@Override
72-
public boolean isStatic() {
73-
return false;
74-
}
70+
private static class FsIfCutOffFunction extends ContentFunctionAbstract {
7571

7672
@Override
7773
public String calculate(LayoutContext c, FSFunction function) {
@@ -99,11 +95,7 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
9995
}
10096
}
10197

102-
private static abstract class PageNumberFunction implements ContentFunction {
103-
@Override
104-
public boolean isStatic() {
105-
return false;
106-
}
98+
private static abstract class PageNumberFunction extends ContentFunctionAbstract {
10799

108100
@Override
109101
public String calculate(LayoutContext c, FSFunction function) {
@@ -153,7 +145,7 @@ protected boolean isCounter(FSFunction function, String counterName) {
153145
}
154146
}
155147

156-
private static class PageCounterFunction extends PageNumberFunction implements ContentFunction {
148+
private static class PageCounterFunction extends PageNumberFunction {
157149
@Override
158150
public String calculate(RenderingContext c, FSFunction function, InlineText text) {
159151
int value = c.getRootLayer().getRelativePageNo(c) + 1;
@@ -166,7 +158,7 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
166158
}
167159
}
168160

169-
private static class PagesCounterFunction extends PageNumberFunction implements ContentFunction {
161+
private static class PagesCounterFunction extends PageNumberFunction {
170162
@Override
171163
public String calculate(RenderingContext c, FSFunction function, InlineText text) {
172164
int value = c.getRootLayer().getRelativePageCount(c);
@@ -183,11 +175,7 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
183175
* Partially implements target counter as specified here:
184176
* http://www.w3.org/TR/2007/WD-css3-gcpm-20070504/#cross-references
185177
*/
186-
private static class TargetCounterFunction implements ContentFunction {
187-
@Override
188-
public boolean isStatic() {
189-
return false;
190-
}
178+
private static class TargetCounterFunction extends ContentFunctionAbstract {
191179

192180
@Override
193181
public String calculate(RenderingContext c, FSFunction function, InlineText text) {
@@ -265,11 +253,7 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
265253
* is not resolved to an absolute url.<br>
266254
* We only support returning the content of the target element, not a specific pseudo element.
267255
*/
268-
private static class TargetTextFunction implements ContentFunction {
269-
@Override
270-
public boolean isStatic() {
271-
return false;
272-
}
256+
private static class TargetTextFunction extends ContentFunctionAbstract {
273257

274258
@Override
275259
public boolean isCalculableAtLayout() {
@@ -380,11 +364,7 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
380364
* Partially implements leaders as specified here:
381365
* http://www.w3.org/TR/2007/WD-css3-gcpm-20070504/#leaders
382366
*/
383-
public static class LeaderFunction implements ContentFunction {
384-
@Override
385-
public boolean isStatic() {
386-
return false;
387-
}
367+
public static class LeaderFunction extends ContentFunctionAbstract {
388368

389369
@Override
390370
public String calculate(RenderingContext c, FSFunction function, InlineText text) {

openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/derived/FSLinearGradient.java

Lines changed: 6 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,11 @@
22

33
import java.util.ArrayList;
44
import java.util.List;
5-
import java.util.Objects;
6-
75
import com.openhtmltopdf.css.constants.CSSName;
8-
import com.openhtmltopdf.css.constants.Idents;
96
import com.openhtmltopdf.css.parser.CSSPrimitiveValue;
107
import com.openhtmltopdf.css.parser.FSColor;
118
import com.openhtmltopdf.css.parser.FSFunction;
129
import com.openhtmltopdf.css.parser.PropertyValue;
13-
import com.openhtmltopdf.css.parser.property.AbstractPropertyBuilder;
1410
import com.openhtmltopdf.css.parser.property.Conversions;
1511
import com.openhtmltopdf.css.style.CalculatedStyle;
1612
import com.openhtmltopdf.css.style.CssContext;
@@ -62,9 +58,9 @@ public String toString() {
6258

6359
public FSLinearGradient(CalculatedStyle style, FSFunction function, int boxWidth, int boxHeight, CssContext ctx) {
6460
List<PropertyValue> params = function.getParameters();
65-
int stopsStartIndex = getStopsStartIndex(params);
61+
int stopsStartIndex = FSLinearGradientUtil.getStopsStartIndex(params);
6662

67-
float prelimAngle = calculateAngle(params, stopsStartIndex);
63+
float prelimAngle = FSLinearGradientUtil.calculateAngle(params, stopsStartIndex);
6864
prelimAngle = prelimAngle % 360f;
6965
if (prelimAngle < 0) {
7066
prelimAngle += 360f;
@@ -75,10 +71,6 @@ public FSLinearGradient(CalculatedStyle style, FSFunction function, int boxWidth
7571
endPointsFromAngle(_angle, boxWidth, boxHeight);
7672
}
7773

78-
private float deg2rad(final float deg) {
79-
return (float) Math.toRadians(deg);
80-
}
81-
8274
// Compute the endpoints so that a gradient of the given angle
8375
// covers a box of the given size.
8476
// From: https://github.com/WebKit/webkit/blob/master/Source/WebCore/css/CSSGradientValue.cpp
@@ -121,7 +113,7 @@ private void endPointsFromAngle(float angleDeg, final int w, final int h) {
121113

122114
// angleDeg is a "bearing angle" (0deg = N, 90deg = E),
123115
// but tan expects 0deg = E, 90deg = N.
124-
final float slope = (float) Math.tan(deg2rad(90 - angleDeg));
116+
final float slope = (float) Math.tan(FSLinearGradientUtil.deg2rad(90 - angleDeg));
125117

126118
// We find the endpoint by computing the intersection of the line formed by the
127119
// slope,
@@ -163,11 +155,6 @@ private void endPointsFromAngle(float angleDeg, final int w, final int h) {
163155
y1 = (int) (halfHeight + endY);
164156
}
165157

166-
private boolean isLengthOrPercentage(PropertyValue value) {
167-
return AbstractPropertyBuilder.isLengthHelper(value) ||
168-
value.getPrimitiveType() == CSSPrimitiveValue.CSS_PERCENTAGE;
169-
}
170-
171158
private List<StopPoint> calculateStopPoints(
172159
List<PropertyValue> params, CalculatedStyle style, CssContext ctx, float boxWidth, int stopsStartIndex) {
173160

@@ -183,7 +170,7 @@ private List<StopPoint> calculateStopPoints(
183170
color = value.getFSColor();
184171
}
185172

186-
if (i + 1 < params.size() && isLengthOrPercentage(params.get(i + 1))) {
173+
if (i + 1 < params.size() && FSLinearGradientUtil.isLengthOrPercentage(params.get(i + 1))) {
187174

188175
PropertyValue lengthValue = params.get(i + 1);
189176
float length = LengthValue.calcFloatProportionalValue(style, CSSName.BACKGROUND_IMAGE, "",
@@ -207,7 +194,7 @@ private List<StopPoint> calculateStopPoints(
207194
} else if (i == 0) {
208195
ret.add(new StopPoint(pt.getColor(), 0f));
209196
} else if (i == points.size() - 1) {
210-
float len = get100PercentDefaultStopLength(style, ctx, boxWidth);
197+
float len = FSLinearGradientUtil.get100PercentDefaultStopLength(style, ctx, boxWidth);
211198
ret.add(new StopPoint(pt.getColor(), len));
212199
} else {
213200
// Poo, we've got a length-less stop in the middle.
@@ -219,7 +206,7 @@ private List<StopPoint> calculateStopPoints(
219206
int prevWithLengthIndex = getPrevStopPointWithLengthIndex(points, i - 1);
220207

221208
float nextLength = nextWithLengthIndex == -1 ?
222-
get100PercentDefaultStopLength(style, ctx, boxWidth) :
209+
FSLinearGradientUtil.get100PercentDefaultStopLength(style, ctx, boxWidth) :
223210
((StopPoint) points.get(nextWithLengthIndex)).getLength();
224211

225212
float prevLength = prevWithLengthIndex == -1 ? 0 :
@@ -254,11 +241,6 @@ private int getPrevStopPointWithLengthIndex(List<IntermediateStopPoint> points,
254241
return -1;
255242
}
256243

257-
private float get100PercentDefaultStopLength(CalculatedStyle style, CssContext ctx, float boxWidth) {
258-
return LengthValue.calcFloatProportionalValue(style, CSSName.BACKGROUND_IMAGE, "100%",
259-
100f, CSSPrimitiveValue.CSS_PERCENTAGE, boxWidth, ctx);
260-
}
261-
262244
private boolean isStopPointWithLength(IntermediateStopPoint pt) {
263245
return pt.getClass() == StopPoint.class;
264246
}
@@ -272,69 +254,6 @@ private int getNextStopPointWithLengthIndex(List<IntermediateStopPoint> points,
272254
return -1;
273255
}
274256

275-
private int getStopsStartIndex(List<PropertyValue> params) {
276-
if (Objects.equals(params.get(0).getStringValue(), "to")) {
277-
int i = 1;
278-
while (i < params.size() &&
279-
params.get(i).getStringValue() != null &&
280-
Idents.looksLikeABGPosition(params.get(i).getStringValue())) {
281-
i++;
282-
}
283-
284-
return i;
285-
} else {
286-
return 1;
287-
}
288-
}
289-
290-
/**
291-
* Calculates the angle of the linear gradient in degrees.
292-
*/
293-
private float calculateAngle(List<PropertyValue> params, int stopsStartIndex) {
294-
if (Objects.equals(params.get(0).getStringValue(), "to")) {
295-
// The to keyword is followed by one or two position
296-
// idents (in any order).
297-
// linear-gradient( to left top, blue, red);
298-
// linear-gradient( to top right, blue, red);
299-
List<String> positions = new ArrayList<>(2);
300-
301-
for (int i = 1; i < stopsStartIndex; i++) {
302-
positions.add(params.get(i).getStringValue());
303-
}
304-
305-
if (positions.contains("top") && positions.contains("left"))
306-
return 315f;
307-
else if (positions.contains("top") && positions.contains("right"))
308-
return 45f;
309-
else if (positions.contains("bottom") && positions.contains("left"))
310-
return 225f;
311-
else if (positions.contains("bottom") && positions.contains("right"))
312-
return 135f;
313-
else if (positions.contains("bottom"))
314-
return 180f;
315-
else if (positions.contains("left"))
316-
return 270f;
317-
else if (positions.contains("right"))
318-
return 90f;
319-
else
320-
return 0f;
321-
}
322-
else if (params.get(0).getPrimitiveType() == CSSPrimitiveValue.CSS_DEG)
323-
{
324-
// linear-gradient(45deg, ...)
325-
return params.get(0).getFloatValue();
326-
}
327-
else if (params.get(0).getPrimitiveType() == CSSPrimitiveValue.CSS_RAD)
328-
{
329-
// linear-gradient(2rad)
330-
return params.get(0).getFloatValue() * (float) (180 / Math.PI);
331-
}
332-
else
333-
{
334-
return 0f;
335-
}
336-
}
337-
338257
public List<StopPoint> getStopPoints() {
339258
return _stopPoints;
340259
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.openhtmltopdf.css.style.derived;
2+
3+
import com.openhtmltopdf.css.constants.CSSName;
4+
import com.openhtmltopdf.css.constants.Idents;
5+
import com.openhtmltopdf.css.parser.CSSPrimitiveValue;
6+
import com.openhtmltopdf.css.parser.PropertyValue;
7+
import com.openhtmltopdf.css.parser.property.AbstractPropertyBuilder;
8+
import com.openhtmltopdf.css.style.CalculatedStyle;
9+
import com.openhtmltopdf.css.style.CssContext;
10+
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.Objects;
14+
15+
public class FSLinearGradientUtil {
16+
static float deg2rad(final float deg) {
17+
return (float) Math.toRadians(deg);
18+
}
19+
20+
static boolean isLengthOrPercentage(PropertyValue value) {
21+
return AbstractPropertyBuilder.isLengthHelper(value) ||
22+
value.getPrimitiveType() == CSSPrimitiveValue.CSS_PERCENTAGE;
23+
}
24+
25+
static int getStopsStartIndex(List<PropertyValue> params) {
26+
if (Objects.equals(params.get(0).getStringValue(), "to")) {
27+
int i = 1;
28+
while (i < params.size() &&
29+
params.get(i).getStringValue() != null &&
30+
Idents.looksLikeABGPosition(params.get(i).getStringValue())) {
31+
i++;
32+
}
33+
34+
return i;
35+
} else {
36+
return 1;
37+
}
38+
}
39+
40+
static float get100PercentDefaultStopLength(CalculatedStyle style, CssContext ctx, float boxWidth) {
41+
return LengthValue.calcFloatProportionalValue(style, CSSName.BACKGROUND_IMAGE, "100%",
42+
100f, CSSPrimitiveValue.CSS_PERCENTAGE, boxWidth, ctx);
43+
}
44+
45+
/**
46+
* Calculates the angle of the linear gradient in degrees.
47+
*/
48+
static float calculateAngle(List<PropertyValue> params, int stopsStartIndex) {
49+
if (Objects.equals(params.get(0).getStringValue(), "to")) {
50+
// The to keyword is followed by one or two position
51+
// idents (in any order).
52+
// linear-gradient( to left top, blue, red);
53+
// linear-gradient( to top right, blue, red);
54+
List<String> positions = new ArrayList<>(2);
55+
56+
for (int i = 1; i < stopsStartIndex; i++) {
57+
positions.add(params.get(i).getStringValue());
58+
}
59+
60+
if (positions.contains("top") && positions.contains("left"))
61+
return 315f;
62+
else if (positions.contains("top") && positions.contains("right"))
63+
return 45f;
64+
else if (positions.contains("bottom") && positions.contains("left"))
65+
return 225f;
66+
else if (positions.contains("bottom") && positions.contains("right"))
67+
return 135f;
68+
else if (positions.contains("bottom"))
69+
return 180f;
70+
else if (positions.contains("left"))
71+
return 270f;
72+
else if (positions.contains("right"))
73+
return 90f;
74+
else
75+
return 0f;
76+
}
77+
else if (params.get(0).getPrimitiveType() == CSSPrimitiveValue.CSS_DEG)
78+
{
79+
// linear-gradient(45deg, ...)
80+
return params.get(0).getFloatValue();
81+
}
82+
else if (params.get(0).getPrimitiveType() == CSSPrimitiveValue.CSS_RAD)
83+
{
84+
// linear-gradient(2rad)
85+
return params.get(0).getFloatValue() * (float) (180 / Math.PI);
86+
}
87+
else
88+
{
89+
return 0f;
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)