<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>PDPageContentStream.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache PDFBox</a> > <a href="index.source.html" class="el_package">org.apache.pdfbox.pdmodel</a> > <span class="el_source">PDPageContentStream.java</span></div><h1>PDPageContentStream.java</h1><pre class="source lang-java linenums">/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.pdfbox.pdmodel; import java.io.Closeable; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSBase; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream; /** * Provides the ability to write to a page content stream. * * @author Ben Litchfield */ public final class PDPageContentStream extends PDAbstractContentStream implements Closeable { /** * This is to choose what to do with the stream: overwrite, append or prepend. */ <span class="fc" id="L42"> public enum AppendMode</span> { /** * Overwrite the existing page content streams. */ <span class="fc" id="L47"> OVERWRITE, </span> /** * Append the content stream after all existing page content streams. */ <span class="fc" id="L51"> APPEND, </span> /** * Insert before all other page content streams. */ <span class="fc" id="L55"> PREPEND;</span> public boolean isOverwrite() { <span class="fc bfc" id="L59" title="All 2 branches covered."> return this == OVERWRITE;</span> } public boolean isPrepend() { <span class="pc bpc" id="L64" title="1 of 2 branches missed."> return this == PREPEND;</span> } } <span class="fc" id="L68"> private static final Log LOG = LogFactory.getLog(PDPageContentStream.class);</span> <span class="pc" id="L70"> private boolean sourcePageHadContents = false;</span> /** * Create a new PDPage content stream. This constructor overwrites all existing content streams * of this page. * * @param document The document the page is part of. * @param sourcePage The page to write the contents to. * @throws IOException If there is an error writing to the page contents. */ public PDPageContentStream(PDDocument document, PDPage sourcePage) throws IOException { <span class="fc" id="L82"> this(document, sourcePage, AppendMode.OVERWRITE, true, false);</span> <span class="pc bpc" id="L83" title="1 of 2 branches missed."> if (sourcePageHadContents)</span> { <span class="nc" id="L85"> LOG.warn("You are overwriting an existing content, you should use the append mode");</span> } <span class="fc" id="L87"> }</span> /** * Create a new PDPage content stream. If the appendContent parameter is set to * {@link AppendMode#APPEND}, you may want to use * {@link #PDPageContentStream(PDDocument, PDPage, PDPageContentStream.AppendMode, boolean, boolean)} * instead, with the fifth parameter set to true. * * @param document The document the page is part of. * @param sourcePage The page to write the contents to. * @param appendContent Indicates whether content will be overwritten, appended or prepended. * @param compress Tell if the content stream should compress the page contents. * @throws IOException If there is an error writing to the page contents. */ public PDPageContentStream(PDDocument document, PDPage sourcePage, AppendMode appendContent, boolean compress) throws IOException { <span class="fc" id="L104"> this(document, sourcePage, appendContent, compress, false);</span> <span class="fc" id="L105"> }</span> /** * Create a new PDPage content stream. * * @param document The document the page is part of. * @param sourcePage The page to write the contents to. * @param appendContent Indicates whether content will be overwritten, appended or prepended. * @param compress Tell if the content stream should compress the page contents. * @param resetContext Tell if the graphic context should be reset. This is only relevant when * the appendContent parameter is set to {@link AppendMode#APPEND}. You should use this when * appending to an existing stream, because the existing stream may have changed graphic * properties (e.g. scaling, rotation). * @throws IOException If there is an error writing to the page contents. */ public PDPageContentStream(PDDocument document, PDPage sourcePage, AppendMode appendContent, boolean compress, boolean resetContext) throws IOException { <span class="fc" id="L123"> this(document, sourcePage, appendContent, compress, resetContext, new PDStream(document),</span> <span class="fc bfc" id="L124" title="All 2 branches covered."> sourcePage.getResources() != null ? sourcePage.getResources() : new PDResources());</span> <span class="fc" id="L125"> }</span> private PDPageContentStream(PDDocument document, PDPage sourcePage, AppendMode appendContent, boolean compress, boolean resetContext,PDStream stream, PDResources resources) throws IOException { <span class="fc bfc" id="L131" title="All 2 branches covered."> super(document, stream.createOutputStream(compress ? COSName.FLATE_DECODE : null), resources);</span> // propagate resources to the page <span class="fc bfc" id="L134" title="All 2 branches covered."> if (sourcePage.getResources() == null)</span> { <span class="fc" id="L136"> sourcePage.setResources(resources);</span> } // If request specifies the need to append/prepend to the document <span class="fc bfc" id="L140" title="All 4 branches covered."> if (!appendContent.isOverwrite() && sourcePage.hasContents())</span> { // Add new stream to contents array <span class="fc" id="L143"> COSBase contents = sourcePage.getCOSObject().getDictionaryObject(COSName.CONTENTS);</span> COSArray array; <span class="fc bfc" id="L145" title="All 2 branches covered."> if (contents instanceof COSArray)</span> { // If contents is already an array, a new stream is simply appended to it <span class="fc" id="L148"> array = (COSArray) contents;</span> } else { // Creates a new array and adds the current stream plus a new one to it <span class="fc" id="L153"> array = new COSArray();</span> <span class="fc" id="L154"> array.add(contents);</span> } <span class="pc bpc" id="L157" title="1 of 2 branches missed."> if (appendContent.isPrepend())</span> { <span class="nc" id="L159"> array.add(0, stream.getCOSObject());</span> } else { <span class="fc" id="L163"> array.add(stream);</span> } // save the initial/unmodified graphics context <span class="fc bfc" id="L167" title="All 2 branches covered."> if (resetContext)</span> { // create a new stream to prefix existing stream <span class="fc" id="L170"> PDStream prefixStream = new PDStream(document);</span> // save the pre-append graphics state <span class="fc" id="L173"> try (OutputStream prefixOut = prefixStream.createOutputStream())</span> { <span class="fc" id="L175"> prefixOut.write("q".getBytes(StandardCharsets.US_ASCII));</span> <span class="fc" id="L176"> prefixOut.write('\n');</span> } // insert the new stream at the beginning <span class="fc" id="L180"> array.add(0, prefixStream.getCOSObject());</span> } // Sets the compoundStream as page contents <span class="fc" id="L184"> sourcePage.getCOSObject().setItem(COSName.CONTENTS, array);</span> // restore the pre-append graphics state <span class="fc bfc" id="L187" title="All 2 branches covered."> if (resetContext)</span> { <span class="fc" id="L189"> restoreGraphicsState();</span> } <span class="fc" id="L191"> }</span> else { <span class="fc" id="L194"> sourcePageHadContents = sourcePage.hasContents();</span> <span class="fc" id="L195"> sourcePage.setContents(stream);</span> } // configure NumberFormat <span class="fc" id="L199"> setMaximumFractionDigits(5);</span> <span class="fc" id="L200"> }</span> /** * Create a new appearance stream. Note that this is not actually a "page" content stream. * * @param doc The document the page is part of. * @param appearance The appearance stream to write to. * @throws IOException If there is an error writing to the page contents. */ public PDPageContentStream(PDDocument doc, PDAppearanceStream appearance) throws IOException { <span class="nc" id="L211"> this (doc, appearance, appearance.getStream().createOutputStream()); </span> <span class="nc" id="L212"> }</span> /** * Create a new appearance stream. Note that this is not actually a "page" content stream. * * @param doc The document the appearance is part of. * @param appearance The appearance stream to add to. * @param outputStream The appearances output stream to write to. */ public PDPageContentStream(PDDocument doc, PDAppearanceStream appearance, OutputStream outputStream) { <span class="nc" id="L223"> super(doc, outputStream, appearance.getResources());</span> <span class="nc" id="L224"> }</span> /** * This will append raw commands to the content stream. * * @param commands The commands to append to the stream. * @throws IOException If an error occurs while writing to the stream. * @deprecated Usage of this method is discouraged. */ @Deprecated public void appendRawCommands(String commands) throws IOException { <span class="nc" id="L236"> write(commands);</span> <span class="nc" id="L237"> }</span> /** * This will append raw commands to the content stream. * * @param commands The commands to append to the stream. * @throws IOException If an error occurs while writing to the stream. * @deprecated Usage of this method is discouraged. */ @Deprecated public void appendRawCommands(byte[] commands) throws IOException { <span class="nc" id="L249"> write(commands);</span> <span class="nc" id="L250"> }</span> /** * This will append raw commands to the content stream. * * @param data Append a raw byte to the stream. * @throws IOException If an error occurs while writing to the stream. * @deprecated Usage of this method is discouraged. */ @Deprecated public void appendRawCommands(int data) throws IOException { <span class="nc" id="L262"> writeOperand(data);</span> <span class="nc" id="L263"> }</span> /** * This will append raw commands to the content stream. * * @param data Append a formatted double value to the stream. * @throws IOException If an error occurs while writing to the stream. * @deprecated Usage of this method is discouraged. */ @Deprecated public void appendRawCommands(double data) throws IOException { <span class="nc" id="L275"> writeOperand((float) data);</span> <span class="nc" id="L276"> }</span> /** * This will append raw commands to the content stream. * * @param data Append a formatted float value to the stream. * @throws IOException If an error occurs while writing to the stream. * @deprecated Usage of this method is discouraged. */ @Deprecated public void appendRawCommands(float data) throws IOException { <span class="nc" id="L288"> writeOperand(data);</span> <span class="nc" id="L289"> }</span> } </pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html>