Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design refactoring #817

Merged
merged 3 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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