Support for linearGradient Color Scheme in Layout, CSS and SVG
Introduction
A commonly used element in both CSS and SVG frameworks is linearGradient, which allows for progressive transitions between colors in graphical objects. With the release of iText 7 Core 7.1.12, we're thrilled to introduce support for linearGradient in both CSS and SVG within the iText 7 Core library and version 3.0.1 of the pdfHTML add-on.
In the following code snippets, we demonstrate some of linearGradient's more nuanced applications using the iText 7 Core layout engine. If you're looking for how to use this functionality with pdfHTML, we've created a separate article with a couple of examples.
Applying linearGradient to a Paragraph Object
The following addLinearGradientAsElementBackground function example generates a PDF paragraph object colored with a linearGradient which transitions from red to green to blue. This function implements the new AbstractLinearGradientBuilder class., which empowers users to build intricate linearGradient color schemes with minimal code.
JAVA
package com.itextpdf.samples.sandbox.graphics;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.colors.gradients.AbstractLinearGradientBuilder;
import com.itextpdf.kernel.colors.gradients.GradientColorStop;
import com.itextpdf.kernel.colors.gradients.LinearGradientBuilder;
import com.itextpdf.kernel.colors.gradients.StrategyBasedLinearGradientBuilder;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Div;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.BackgroundImage;
import com.itextpdf.layout.property.Property;
import java.io.File;
public class LinearGradientsInLayoutParagraph {
public static final String DEST = "./results/linearGradientParagraph.pdf";
public static void main(String[] args) throws Exception {
File file = new File(DEST);
file.getParentFile().mkdirs();
new LinearGradientsInLayout().manipulatePdf();
}
protected void manipulatePdf() throws Exception {
Document doc = new Document(new PdfDocument(new PdfWriter(DEST)));
addLinearGradientAsElementBackground(doc);
doc.close();
}
private void addLinearGradientAsElementBackground(Document doc) {
doc.add(new Paragraph("The \"addLinearGradientAsElementBackground\" starts here."));
AbstractLinearGradientBuilder gradientBuilder = new StrategyBasedLinearGradientBuilder()
.addColorStop(new GradientColorStop(ColorConstants.RED.getColorValue()))
.addColorStop(new GradientColorStop(ColorConstants.GREEN.getColorValue()))
.addColorStop(new GradientColorStop(ColorConstants.BLUE.getColorValue()));
BackgroundImage backgroundImage = new BackgroundImage(gradientBuilder);
if (backgroundImage.isBackgroundSpecified()) {
String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " +
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi " +
"ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit " +
"in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui " +
"officia deserunt mollit anim id est laborum. ";
Div div = new Div().add(new Paragraph(text + text + text));
div.setProperty(Property.BACKGROUND_IMAGE, backgroundImage);
doc.add(div);
}
}
}
C#
using System;
using System.IO;
using iText.Kernel.Colors;
using iText.Kernel.Colors.Gradients;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Borders;
using iText.Layout.Element;
using iText.Layout.Properties;
namespace iText.Samples.Sandbox.Graphics
{
public class LinearGradientsInLayoutParagraph
{
public static readonly string DEST = "results/linearGradientParagraph.pdf";
public static void Main(String[] args)
{
FileInfo file = new FileInfo(DEST);
file.Directory.Create();
new LinearGradientsInLayout().ManipulatePdf();
}
protected void ManipulatePdf()
{
Document doc = new Document(new PdfDocument(new PdfWriter(DEST)));
AddLinearGradientAsElementBackground(doc);
doc.Close();
}
private void AddLinearGradientAsElementBackground(Document doc)
{
doc.Add(new Paragraph("The \"addLinearGradientAsElementBackground\" starts here."));
AbstractLinearGradientBuilder gradientBuilder = new StrategyBasedLinearGradientBuilder()
.AddColorStop(new GradientColorStop(ColorConstants.RED.GetColorValue()))
.AddColorStop(new GradientColorStop(ColorConstants.GREEN.GetColorValue()))
.AddColorStop(new GradientColorStop(ColorConstants.BLUE.GetColorValue()));
BackgroundImage backgroundImage = new BackgroundImage(gradientBuilder);
if (backgroundImage.IsBackgroundSpecified())
{
String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " +
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi " +
"ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit " +
"in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui " +
"officia deserunt mollit anim id est laborum. ";
Div div = new Div().Add(new Paragraph(text + text + text));
div.SetProperty(Property.BACKGROUND_IMAGE, backgroundImage);
doc.Add(div);
}
}
}
}
Below is the output of addLinearGradientAsElementBackground:
Applying a Position-Based linearGradient Coloring Scheme
The createColorBasedOnAbsolutelyPositionedLinearGradient function in the following code snippet generates and applies a linearGradient color which transitions from red to pink to blue. This gradient is generated to span over the entire page. Based on where objects with this page-spanning color are placed, they will feature different colors on the linearGradient scale. In the example below, we apply this gradient to the border of a new paragraph object. We then create a small table with the same colored borders.
JAVA
package com.itextpdf.samples.sandbox.graphics;
import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.colors.gradients.AbstractLinearGradientBuilder;
import com.itextpdf.kernel.colors.gradients.GradientColorStop;
import com.itextpdf.kernel.colors.gradients.LinearGradientBuilder;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.UnitValue;
import java.io.File;
public class LinearGradientsInLayoutPositionBased {
public static final String DEST = "./results/linearGradientPositionBased.pdf";
public static void main(String[] args) throws Exception {
File file = new File(DEST);
file.getParentFile().mkdirs();
new LinearGradientsInLayout().manipulatePdf();
}
protected void manipulatePdf() throws Exception {
Document doc = new Document(new PdfDocument(new PdfWriter(DEST)));
createColorBasedOnAbsolutelyPositionedLinearGradient(doc);
doc.close();
}
private void createColorBasedOnAbsolutelyPositionedLinearGradient(Document doc){
// The below such linear gradient spans across the whole page and therefore color created from it will be
// different based at the location of the page.
AbstractLinearGradientBuilder gradientBuilder = new LinearGradientBuilder()
.setGradientVector(PageSize.A4.getLeft(), PageSize.A4.getBottom(), PageSize.A4.getRight(), PageSize.A4.getTop())
.addColorStop(new GradientColorStop(ColorConstants.RED.getColorValue()))
.addColorStop(new GradientColorStop(ColorConstants.PINK.getColorValue()))
.addColorStop(new GradientColorStop(ColorConstants.BLUE.getColorValue()));
Color gradientColor = gradientBuilder.buildColor(PageSize.A4.clone(), null, doc.getPdfDocument());
doc.add(new Paragraph("The \"createColorBasedOnAbsolutelyPositionedLinearGradient\" starts here.").setFontColor(gradientColor));
String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In dapibus aliquam quam. Aliquam at tincidunt mauris. "
+ "Curabitur mollis leo venenatis diam bibendum consectetur. Etiam at lacus ultricies, vulputate dui nec, mattis ex. "
+ "Sed quis leo in purus consectetur sodales. Nam sit amet felis orci. Aliquam non lacus ut nisi hendrerit sollicitudin "
+ "a at ligula. Vivamus condimentum vehicula nulla a blandit. In sit amet ex hendrerit augue iaculis consectetur. "
+ "Etiam semper risus pulvinar, faucibus ex eu, tristique felis. Integer ullamcorper ipsum ac nisi vulputate malesuada."
+ "Nunc sit amet ipsum sollicitudin, consequat lectus ac, finibus erat. Vivamus malesuada a leo vel consequat."
+ "Maecenas ac blandit velit, at eleifend ipsum. Praesent dui orci, molestie a semper eu, varius nec augue. "
+ "Ut vehicula libero ligula, id tristique nisi convallis et. Curabitur nec velit ut nisi commodo rhoncus "
+ "non eu ipsum. Pellentesque eget mauris ex. Nullam et lectus et eros sollicitudin tincidunt. Phasellus "
+ "commodo erat nec diam consectetur elementum. Cras pellentesque commodo est, vel viverra nisi "
+ "vulputate ac. Curabitur interdum nulla at viverra varius. Donec porttitor erat lacus, ac efficitur "
+ "arcu malesuada dignissim. Aenean pretium ex tortor, a porttitor quam mollis vitae. Etiam id nibh dolor."
+ " Curabitur vel ligula tortor. Etiam vestibulum velit neque, a mattis tortor vehicula sed. Sed sit amet "
+ "ipsum leo. Mauris et tincidunt ex. Donec vehicula, magna eget convallis suscipit, nisi tellus ullamcorper "
+ "massa, eu commodo lectus massa ac orci. Fusce nec gravida justo, ac lacinia metus. Etiam porttitor "
+ "massa odio, vestibulum semper ipsum tristique eget. Donec semper elit nibh, tristique placerat arcu "
+ "egestas et. Pellentesque leo metus, sodales in nisi ut, condimentum dignissim eros. Duis maximus eu "
+ "mi faucibus mattis. Quisque leo urna, hendrerit eu finibus nec, ullamcorper at nunc.";
Paragraph paragraph = new Paragraph(text).setBorder(new SolidBorder(gradientColor, 5));
Table table = new Table(UnitValue.createPercentArray(3)).useAllAvailableWidth();
Cell cell = new Cell().add(new Paragraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit."));
table.addCell(cell);
cell = new Cell().add(new Paragraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit."));
table.addCell(cell);
cell = new Cell().add(new Paragraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit."));
table.addCell(cell);
table.setBorder(new SolidBorder(gradientColor, 9));
doc
.add(paragraph)
.add(table);
}
}
C#
using System;
using System.IO;
using iText.Kernel.Colors;
using iText.Kernel.Colors.Gradients;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Borders;
using iText.Layout.Element;
using iText.Layout.Properties;
namespace iText.Samples.Sandbox.Graphics
{
public class LinearGradientsInLayoutPositionBased
{
public static readonly string DEST = "results/linearGradientParagraph.pdf";
public static void Main(String[] args)
{
FileInfo file = new FileInfo(DEST);
file.Directory.Create();
new LinearGradientsInLayout().ManipulatePdf();
}
protected void ManipulatePdf()
{
Document doc = new Document(new PdfDocument(new PdfWriter(DEST)));
CreateColorBasedOnAbsolutelyPositionedLinearGradient(doc);
doc.Close();
}
private void CreateColorBasedOnAbsolutelyPositionedLinearGradient(Document doc)
{
// The below such linear gradient spans across the whole page and therefore color created from it will be
// different based at the location of the page
AbstractLinearGradientBuilder gradientBuilder = new LinearGradientBuilder()
.SetGradientVector(PageSize.A4.GetLeft(), PageSize.A4.GetBottom(), PageSize.A4.GetRight(), PageSize.A4.GetTop())
.AddColorStop(new GradientColorStop(ColorConstants.RED.GetColorValue()))
.AddColorStop(new GradientColorStop(ColorConstants.PINK.GetColorValue()))
.AddColorStop(new GradientColorStop(ColorConstants.BLUE.GetColorValue()));
Color gradientColor = gradientBuilder.BuildColor(PageSize.A4.Clone(), null, doc.GetPdfDocument());
doc.Add(new Paragraph("The \"createColorBasedOnAbsolutelyPositionedLinearGradient\" starts here.").SetFontColor(gradientColor));
String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In dapibus aliquam quam. Aliquam at tincidunt mauris. "
+ "Curabitur mollis leo venenatis diam bibendum consectetur. Etiam at lacus ultricies, vulputate dui nec, mattis ex. "
+ "Sed quis leo in purus consectetur sodales. Nam sit amet felis orci. Aliquam non lacus ut nisi hendrerit sollicitudin "
+ "a at ligula. Vivamus condimentum vehicula nulla a blandit. In sit amet ex hendrerit augue iaculis consectetur. "
+ "Etiam semper risus pulvinar, faucibus ex eu, tristique felis. Integer ullamcorper ipsum ac nisi vulputate malesuada."
+ "Nunc sit amet ipsum sollicitudin, consequat lectus ac, finibus erat. Vivamus malesuada a leo vel consequat."
+ "Maecenas ac blandit velit, at eleifend ipsum. Praesent dui orci, molestie a semper eu, varius nec augue. "
+ "Ut vehicula libero ligula, id tristique nisi convallis et. Curabitur nec velit ut nisi commodo rhoncus "
+ "non eu ipsum. Pellentesque eget mauris ex. Nullam et lectus et eros sollicitudin tincidunt. Phasellus "
+ "commodo erat nec diam consectetur elementum. Cras pellentesque commodo est, vel viverra nisi "
+ "vulputate ac. Curabitur interdum nulla at viverra varius. Donec porttitor erat lacus, ac efficitur "
+ "arcu malesuada dignissim. Aenean pretium ex tortor, a porttitor quam mollis vitae. Etiam id nibh dolor."
+ " Curabitur vel ligula tortor. Etiam vestibulum velit neque, a mattis tortor vehicula sed. Sed sit amet "
+ "ipsum leo. Mauris et tincidunt ex. Donec vehicula, magna eget convallis suscipit, nisi tellus ullamcorper "
+ "massa, eu commodo lectus massa ac orci. Fusce nec gravida justo, ac lacinia metus. Etiam porttitor "
+ "massa odio, vestibulum semper ipsum tristique eget. Donec semper elit nibh, tristique placerat arcu "
+ "egestas et. Pellentesque leo metus, sodales in nisi ut, condimentum dignissim eros. Duis maximus eu "
+ "mi faucibus mattis. Quisque leo urna, hendrerit eu finibus nec, ullamcorper at nunc.";
Paragraph paragraph = new Paragraph(text).SetBorder(new SolidBorder(gradientColor, 5));
Table table = new Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth();
Cell cell = new Cell().Add(new Paragraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit."));
table.AddCell(cell);
cell = new Cell().Add(new Paragraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit."));
table.AddCell(cell);
cell = new Cell().Add(new Paragraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit."));
table.AddCell(cell);
table.SetBorder(new SolidBorder(gradientColor, 9));
doc
.Add(paragraph)
.Add(table);
}
}
}
Below is the output of createColorBasedOnAbsolutelyPositionedLinearGradient. As you can see, the linearGradient coloring progresses between the paragraph and table despite them being different layout objects.
linearGradient can be applied to any iText 7 Core layout engine object. Apart from the layout engine, linearGradient will function correctly when a user includes the option in their HTML or CSS source code.
Note: iText's current implementation of linearGradient does not include support for non-opaque color gradients.