'How can I do Text Outlines with PDFBox?

My goal is to be able to manage text outlines with PDFBox.

I have been trying to draw a grey text with a black outline.

Like so :

Like so

I've been looking for a few days and I can't seem to find a solution.

I've tried playing with the fill and stroke functions without any success.

Does anyone know how to get the result I'm looking for with PDFBox ?

Here a simple code to illustrate what I'm trying to do.

In this case I set the non stroking color (fill) to grey and the stroking color (outline) to black.

However, when I try to specify a line width for the outline of the text or the stroke command, I get error messages saying it's not allowed with texts.

I would really appreciate any help.

package text_outline;

import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;

/**
 *
 * @author User
 */
public class Text_Outline {

    public static void main(String[] args) {

    // Create PDF Document
    PDDocument MAIN_DOC = new PDDocument();
    
    try {
        // Create page
        PDPage PAGE = new PDPage();
        
        // Create PDPageContentStream for the page
        PDPageContentStream contentStream = new PDPageContentStream(MAIN_DOC, PAGE);
        
        // Begin text
        contentStream.beginText(); 
        contentStream.newLineAtOffset(25, 700);
        
        // Select font
        File fontFile = new File("C:\\WINDOWS\\FONTS\\ARIALBD.TTF");
        PDFont TTFFnt= PDType0Font.load(MAIN_DOC, fontFile);
        contentStream.setFont(TTFFnt, 100);
        
        // Set non stroking color to grey
        contentStream.setNonStrokingColor(179, 179, 179);
        
        // Set stroking color to black
        contentStream.setStrokingColor(Color.BLACK);
                
        // Set text content to HELLO and show
        contentStream.showText("HELLO");
        
        /* setLineWidth not allowed with texts. I get this error :
        Exception in thread "main" java.lang.IllegalStateException: Error: setLineWidth is not allowed within a text block.   */
        contentStream.setLineWidth(10);
        
        /* Stroke not allowed with texts. I get this error :
        Exception in thread "main" java.lang.IllegalStateException: Error: stroke is not allowed within a text block.        */
        contentStream.stroke();
                
        // End text
        contentStream.endText();
        // Close PDPageContentStream
        contentStream.close();
        // Add page to document
        MAIN_DOC.addPage(PAGE);
        
        //Saving the document
        MAIN_DOC.save("c:\\temp\\Text_Outline.pdf");
                        
        //Closing the document
        MAIN_DOC.close();
            
            
        } catch (IOException ex) {
            Logger.getLogger(Text_Outline.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
}


Solution 1:[1]

By default text is drawn in rendering mode "fill". You want "fill & stroke", so you have to add

contentStream.setRenderingMode(RenderingMode.FILL_STROKE);

to your text object.

Solution 2:[2]

If anyone needs it, here is a working example for text outlines with PDFBox.

package text_outline;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode;

public class Text_Outline {

    public static void main(String[] args) {

    // Create PDF Document
    PDDocument MAIN_DOC = new PDDocument();
    
    try {
        // Create page
        PDPage PAGE = new PDPage();
        
        // Create PDPageContentStream for the page
        PDPageContentStream contentStream = new PDPageContentStream(MAIN_DOC, PAGE);
        
        // Set contentStream Rendering Mode to Fill & Stroke
        contentStream.setRenderingMode(RenderingMode.FILL_STROKE);
        
        // Set outline width (Must be before beginText)
        contentStream.setLineWidth(3);
        
        // Set non stroking color to grey
        contentStream.setNonStrokingColor(179, 179, 179);
        
        // Set stroking color to black
        contentStream.setStrokingColor(Color.BLACK);

        // Begin text
        contentStream.beginText(); 
        
        // Set text position
        contentStream.newLineAtOffset(25, 700);
        
        // Select font
        File fontFile = new File("C:\\WINDOWS\\FONTS\\ARIALBD.TTF");
        PDFont TTFFnt= PDType0Font.load(MAIN_DOC, fontFile);
        contentStream.setFont(TTFFnt, 100);
                               
        // Set text content to HELLO and show
        contentStream.showText("HELLO");
                        
        // End text
        contentStream.endText();
        
        // Close PDPageContentStream
        contentStream.close();
        
        // Add page to document
        MAIN_DOC.addPage(PAGE);
        
        //Saving the document
        MAIN_DOC.save("c:\\temp\\Text_Outline.pdf");
                        
        //Closing the document
        MAIN_DOC.close();
            
            
        } catch (IOException ex) {
            Logger.getLogger(Text_Outline.class.getName()).log(Level.SEVERE, null, ex);
        }
    
    }
    
}

For this result :

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mkl
Solution 2 Thomas