<?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>PDInkAppearanceHandler.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.interactive.annotation.handlers</a> > <span class="el_source">PDInkAppearanceHandler.java</span></div><h1>PDInkAppearanceHandler.java</h1><pre class="source lang-java linenums">/* * Copyright 2018 The Apache Software Foundation. * * Licensed 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.interactive.annotation.handlers; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.pdfbox.pdmodel.graphics.color.PDColor; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationInk; import org.apache.pdfbox.pdmodel.PDAppearanceContentStream; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.common.PDRectangle; /** * Handler to generate the ink annotations appearance. * */ public class PDInkAppearanceHandler extends PDAbstractAppearanceHandler { <span class="nc" id="L35"> private static final Log LOG = LogFactory.getLog(PDInkAppearanceHandler.class);</span> public PDInkAppearanceHandler(PDAnnotation annotation) { <span class="nc" id="L39"> super(annotation);</span> <span class="nc" id="L40"> }</span> public PDInkAppearanceHandler(PDAnnotation annotation, PDDocument document) { <span class="nc" id="L44"> super(annotation, document);</span> <span class="nc" id="L45"> }</span> @Override public void generateNormalAppearance() { <span class="nc" id="L50"> PDAnnotationInk ink = (PDAnnotationInk) getAnnotation();</span> <span class="nc" id="L51"> PDColor color = ink.getColor();</span> <span class="nc bnc" id="L52" title="All 4 branches missed."> if (color == null || color.getComponents().length == 0)</span> { <span class="nc" id="L54"> return;</span> } // PDF spec does not mention /Border for ink annotations, but it is used if /BS is not available <span class="nc" id="L57"> AnnotationBorder ab = AnnotationBorder.getAnnotationBorder(ink, ink.getBorderStyle());</span> <span class="nc bnc" id="L58" title="All 2 branches missed."> if (Float.compare(ab.width, 0) == 0)</span> { <span class="nc" id="L60"> return;</span> } // Adjust rectangle even if not empty // file from PDF.js issue 13447 //TODO in a class structure this should be overridable <span class="nc" id="L66"> float minX = Float.MAX_VALUE;</span> <span class="nc" id="L67"> float minY = Float.MAX_VALUE;</span> <span class="nc" id="L68"> float maxX = Float.MIN_VALUE;</span> <span class="nc" id="L69"> float maxY = Float.MIN_VALUE;</span> <span class="nc bnc" id="L70" title="All 2 branches missed."> for (float[] pathArray : ink.getInkList())</span> { <span class="nc" id="L72"> int nPoints = pathArray.length / 2;</span> <span class="nc bnc" id="L73" title="All 2 branches missed."> for (int i = 0; i < nPoints; ++i)</span> { <span class="nc" id="L75"> float x = pathArray[i * 2];</span> <span class="nc" id="L76"> float y = pathArray[i * 2 + 1];</span> <span class="nc" id="L77"> minX = Math.min(minX, x);</span> <span class="nc" id="L78"> minY = Math.min(minY, y);</span> <span class="nc" id="L79"> maxX = Math.max(maxX, x);</span> <span class="nc" id="L80"> maxY = Math.max(maxY, y);</span> } } <span class="nc" id="L83"> PDRectangle rect = ink.getRectangle();</span> <span class="nc bnc" id="L84" title="All 2 branches missed."> if (rect == null)</span> { <span class="nc" id="L86"> return;</span> } <span class="nc" id="L88"> rect.setLowerLeftX(Math.min(minX - ab.width * 2, rect.getLowerLeftX()));</span> <span class="nc" id="L89"> rect.setLowerLeftY(Math.min(minY - ab.width * 2, rect.getLowerLeftY()));</span> <span class="nc" id="L90"> rect.setUpperRightX(Math.max(maxX + ab.width * 2, rect.getUpperRightX()));</span> <span class="nc" id="L91"> rect.setUpperRightY(Math.max(maxY + ab.width * 2, rect.getUpperRightY()));</span> <span class="nc" id="L92"> ink.setRectangle(rect);</span> <span class="nc" id="L94"> try (PDAppearanceContentStream cs = getNormalAppearanceAsContentStream())</span> { <span class="nc" id="L96"> setOpacity(cs, ink.getConstantOpacity());</span> <span class="nc" id="L98"> cs.setStrokingColor(color);</span> <span class="nc bnc" id="L99" title="All 2 branches missed."> if (ab.dashArray != null)</span> { <span class="nc" id="L101"> cs.setLineDashPattern(ab.dashArray, 0);</span> } <span class="nc" id="L103"> cs.setLineWidth(ab.width);</span> <span class="nc bnc" id="L105" title="All 2 branches missed."> for (float[] pathArray : ink.getInkList())</span> { <span class="nc" id="L107"> int nPoints = pathArray.length / 2;</span> // "When drawn, the points shall be connected by straight lines or curves // in an implementation-dependent way" - we do lines. <span class="nc bnc" id="L111" title="All 2 branches missed."> for (int i = 0; i < nPoints; ++i)</span> { <span class="nc" id="L113"> float x = pathArray[i * 2];</span> <span class="nc" id="L114"> float y = pathArray[i * 2 + 1];</span> <span class="nc bnc" id="L116" title="All 2 branches missed."> if (i == 0)</span> { <span class="nc" id="L118"> cs.moveTo(x, y);</span> } else { <span class="nc" id="L122"> cs.lineTo(x, y);</span> } } <span class="nc" id="L125"> cs.stroke();</span> } } <span class="nc" id="L128"> catch (IOException ex)</span> { <span class="nc" id="L130"> LOG.error(ex);</span> <span class="nc" id="L131"> }</span> <span class="nc" id="L132"> }</span> @Override public void generateRolloverAppearance() { // No rollover appearance generated <span class="nc" id="L138"> }</span> @Override public void generateDownAppearance() { // No down appearance generated <span class="nc" id="L144"> }</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>