Skip to content

Commit

Permalink
Merge pull request #817 from ad619659/design_refactorings
Browse files Browse the repository at this point in the history
Design refactoring for CounterFunction/FSLinearGradient
  • Loading branch information
danfickle authored Apr 1, 2022
2 parents 9ea759c + ab156f6 commit 780ba56
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 142 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.openhtmltopdf.context;

import com.openhtmltopdf.css.extend.ContentFunction;

public abstract class ContentFunctionAbstract implements ContentFunction {
public boolean isStatic() {
return false;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@ public void registerFunction(ContentFunction function) {
* Example:
* <code>content: "Page " counter(page) -fs-if-cut-off(" continued") " of " counter(pages);</code>
*/
private static class FsIfCutOffFunction implements ContentFunction {
@Override
public boolean isStatic() {
return false;
}
private static class FsIfCutOffFunction extends ContentFunctionAbstract {

@Override
public String calculate(LayoutContext c, FSFunction function) {
Expand Down Expand Up @@ -99,11 +95,7 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
}
}

private static abstract class PageNumberFunction implements ContentFunction {
@Override
public boolean isStatic() {
return false;
}
private static abstract class PageNumberFunction extends ContentFunctionAbstract {

@Override
public String calculate(LayoutContext c, FSFunction function) {
Expand Down Expand Up @@ -153,7 +145,7 @@ protected boolean isCounter(FSFunction function, String counterName) {
}
}

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

private static class PagesCounterFunction extends PageNumberFunction implements ContentFunction {
private static class PagesCounterFunction extends PageNumberFunction {
@Override
public String calculate(RenderingContext c, FSFunction function, InlineText text) {
int value = c.getRootLayer().getRelativePageCount(c);
Expand All @@ -183,11 +175,7 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
* Partially implements target counter as specified here:
* http://www.w3.org/TR/2007/WD-css3-gcpm-20070504/#cross-references
*/
private static class TargetCounterFunction implements ContentFunction {
@Override
public boolean isStatic() {
return false;
}
private static class TargetCounterFunction extends ContentFunctionAbstract {

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

@Override
public boolean isCalculableAtLayout() {
Expand Down Expand Up @@ -380,11 +364,7 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
* Partially implements leaders as specified here:
* http://www.w3.org/TR/2007/WD-css3-gcpm-20070504/#leaders
*/
public static class LeaderFunction implements ContentFunction {
@Override
public boolean isStatic() {
return false;
}
public static class LeaderFunction extends ContentFunctionAbstract {

@Override
public String calculate(RenderingContext c, FSFunction function, InlineText text) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import com.openhtmltopdf.css.constants.CSSName;
import com.openhtmltopdf.css.constants.Idents;
import com.openhtmltopdf.css.parser.CSSPrimitiveValue;
import com.openhtmltopdf.css.parser.FSColor;
import com.openhtmltopdf.css.parser.FSFunction;
import com.openhtmltopdf.css.parser.PropertyValue;
import com.openhtmltopdf.css.parser.property.AbstractPropertyBuilder;
import com.openhtmltopdf.css.parser.property.Conversions;
import com.openhtmltopdf.css.style.CalculatedStyle;
import com.openhtmltopdf.css.style.CssContext;
Expand Down Expand Up @@ -62,9 +58,9 @@ public String toString() {

public FSLinearGradient(CalculatedStyle style, FSFunction function, int boxWidth, int boxHeight, CssContext ctx) {
List<PropertyValue> params = function.getParameters();
int stopsStartIndex = getStopsStartIndex(params);
int stopsStartIndex = FSLinearGradientUtil.getStopsStartIndex(params);

float prelimAngle = calculateAngle(params, stopsStartIndex);
float prelimAngle = FSLinearGradientUtil.calculateAngle(params, stopsStartIndex);
prelimAngle = prelimAngle % 360f;
if (prelimAngle < 0) {
prelimAngle += 360f;
Expand All @@ -75,10 +71,6 @@ public FSLinearGradient(CalculatedStyle style, FSFunction function, int boxWidth
endPointsFromAngle(_angle, boxWidth, boxHeight);
}

private float deg2rad(final float deg) {
return (float) Math.toRadians(deg);
}

// Compute the endpoints so that a gradient of the given angle
// covers a box of the given size.
// From: https://github.com/WebKit/webkit/blob/master/Source/WebCore/css/CSSGradientValue.cpp
Expand Down Expand Up @@ -121,7 +113,7 @@ private void endPointsFromAngle(float angleDeg, final int w, final int h) {

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

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

private boolean isLengthOrPercentage(PropertyValue value) {
return AbstractPropertyBuilder.isLengthHelper(value) ||
value.getPrimitiveType() == CSSPrimitiveValue.CSS_PERCENTAGE;
}

private List<StopPoint> calculateStopPoints(
List<PropertyValue> params, CalculatedStyle style, CssContext ctx, float boxWidth, int stopsStartIndex) {

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

if (i + 1 < params.size() && isLengthOrPercentage(params.get(i + 1))) {
if (i + 1 < params.size() && FSLinearGradientUtil.isLengthOrPercentage(params.get(i + 1))) {

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

float nextLength = nextWithLengthIndex == -1 ?
get100PercentDefaultStopLength(style, ctx, boxWidth) :
FSLinearGradientUtil.get100PercentDefaultStopLength(style, ctx, boxWidth) :
((StopPoint) points.get(nextWithLengthIndex)).getLength();

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

private float get100PercentDefaultStopLength(CalculatedStyle style, CssContext ctx, float boxWidth) {
return LengthValue.calcFloatProportionalValue(style, CSSName.BACKGROUND_IMAGE, "100%",
100f, CSSPrimitiveValue.CSS_PERCENTAGE, boxWidth, ctx);
}

private boolean isStopPointWithLength(IntermediateStopPoint pt) {
return pt.getClass() == StopPoint.class;
}
Expand All @@ -272,69 +254,6 @@ private int getNextStopPointWithLengthIndex(List<IntermediateStopPoint> points,
return -1;
}

private int getStopsStartIndex(List<PropertyValue> params) {
if (Objects.equals(params.get(0).getStringValue(), "to")) {
int i = 1;
while (i < params.size() &&
params.get(i).getStringValue() != null &&
Idents.looksLikeABGPosition(params.get(i).getStringValue())) {
i++;
}

return i;
} else {
return 1;
}
}

/**
* Calculates the angle of the linear gradient in degrees.
*/
private float calculateAngle(List<PropertyValue> params, int stopsStartIndex) {
if (Objects.equals(params.get(0).getStringValue(), "to")) {
// The to keyword is followed by one or two position
// idents (in any order).
// linear-gradient( to left top, blue, red);
// linear-gradient( to top right, blue, red);
List<String> positions = new ArrayList<>(2);

for (int i = 1; i < stopsStartIndex; i++) {
positions.add(params.get(i).getStringValue());
}

if (positions.contains("top") && positions.contains("left"))
return 315f;
else if (positions.contains("top") && positions.contains("right"))
return 45f;
else if (positions.contains("bottom") && positions.contains("left"))
return 225f;
else if (positions.contains("bottom") && positions.contains("right"))
return 135f;
else if (positions.contains("bottom"))
return 180f;
else if (positions.contains("left"))
return 270f;
else if (positions.contains("right"))
return 90f;
else
return 0f;
}
else if (params.get(0).getPrimitiveType() == CSSPrimitiveValue.CSS_DEG)
{
// linear-gradient(45deg, ...)
return params.get(0).getFloatValue();
}
else if (params.get(0).getPrimitiveType() == CSSPrimitiveValue.CSS_RAD)
{
// linear-gradient(2rad)
return params.get(0).getFloatValue() * (float) (180 / Math.PI);
}
else
{
return 0f;
}
}

public List<StopPoint> getStopPoints() {
return _stopPoints;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.openhtmltopdf.css.style.derived;

import com.openhtmltopdf.css.constants.CSSName;
import com.openhtmltopdf.css.constants.Idents;
import com.openhtmltopdf.css.parser.CSSPrimitiveValue;
import com.openhtmltopdf.css.parser.PropertyValue;
import com.openhtmltopdf.css.parser.property.AbstractPropertyBuilder;
import com.openhtmltopdf.css.style.CalculatedStyle;
import com.openhtmltopdf.css.style.CssContext;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class FSLinearGradientUtil {
static float deg2rad(final float deg) {
return (float) Math.toRadians(deg);
}

static boolean isLengthOrPercentage(PropertyValue value) {
return AbstractPropertyBuilder.isLengthHelper(value) ||
value.getPrimitiveType() == CSSPrimitiveValue.CSS_PERCENTAGE;
}

static int getStopsStartIndex(List<PropertyValue> params) {
if (Objects.equals(params.get(0).getStringValue(), "to")) {
int i = 1;
while (i < params.size() &&
params.get(i).getStringValue() != null &&
Idents.looksLikeABGPosition(params.get(i).getStringValue())) {
i++;
}

return i;
} else {
return 1;
}
}

static float get100PercentDefaultStopLength(CalculatedStyle style, CssContext ctx, float boxWidth) {
return LengthValue.calcFloatProportionalValue(style, CSSName.BACKGROUND_IMAGE, "100%",
100f, CSSPrimitiveValue.CSS_PERCENTAGE, boxWidth, ctx);
}

/**
* Calculates the angle of the linear gradient in degrees.
*/
static float calculateAngle(List<PropertyValue> params, int stopsStartIndex) {
if (Objects.equals(params.get(0).getStringValue(), "to")) {
// The to keyword is followed by one or two position
// idents (in any order).
// linear-gradient( to left top, blue, red);
// linear-gradient( to top right, blue, red);
List<String> positions = new ArrayList<>(2);

for (int i = 1; i < stopsStartIndex; i++) {
positions.add(params.get(i).getStringValue());
}

if (positions.contains("top") && positions.contains("left"))
return 315f;
else if (positions.contains("top") && positions.contains("right"))
return 45f;
else if (positions.contains("bottom") && positions.contains("left"))
return 225f;
else if (positions.contains("bottom") && positions.contains("right"))
return 135f;
else if (positions.contains("bottom"))
return 180f;
else if (positions.contains("left"))
return 270f;
else if (positions.contains("right"))
return 90f;
else
return 0f;
}
else if (params.get(0).getPrimitiveType() == CSSPrimitiveValue.CSS_DEG)
{
// linear-gradient(45deg, ...)
return params.get(0).getFloatValue();
}
else if (params.get(0).getPrimitiveType() == CSSPrimitiveValue.CSS_RAD)
{
// linear-gradient(2rad)
return params.get(0).getFloatValue() * (float) (180 / Math.PI);
}
else
{
return 0f;
}
}
}
Loading

0 comments on commit 780ba56

Please sign in to comment.