1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.pdfbox.pdmodel.interactive.annotation; 18 19 import org.apache.pdfbox.cos.COSArray; 20 import org.apache.pdfbox.cos.COSDictionary; 21 import org.apache.pdfbox.cos.COSFloat; 22 import org.apache.pdfbox.cos.COSName; 23 import org.apache.pdfbox.pdmodel.graphics.color.PDGamma; 24 25 /** 26 * This is the class that represents a line annotation. 27 * Introduced in PDF 1.3 specification 28 * 29 * @author Paul King 30 * @version $Revision: 1.1 $ 31 */ 32 public class PDAnnotationLine extends PDAnnotationMarkup 33 { 34 35 36 /* 37 * The various values for intent (get/setIT, see the PDF 1.6 reference Table 38 * 8.22 39 */ 40 41 /** 42 * Constant for annotation intent of Arrow. 43 */ 44 public static final String IT_LINE_ARROW = "LineArrow"; 45 46 /** 47 * Constant for annotation intent of a dimension line. 48 */ 49 public static final String IT_LINE_DIMENSION = "LineDimension"; 50 51 /* 52 * The various values for line ending styles, see the PDF 1.6 reference 53 * Table 8.23 54 */ 55 56 /** 57 * Constant for a square line ending. 58 */ 59 public static final String LE_SQUARE = "Square"; 60 61 /** 62 * Constant for a circle line ending. 63 */ 64 public static final String LE_CIRCLE = "Circle"; 65 66 /** 67 * Constant for a diamond line ending. 68 */ 69 public static final String LE_DIAMOND = "Diamond"; 70 71 /** 72 * Constant for a open arrow line ending. 73 */ 74 public static final String LE_OPEN_ARROW = "OpenArrow"; 75 76 /** 77 * Constant for a closed arrow line ending. 78 */ 79 public static final String LE_CLOSED_ARROW = "ClosedArrow"; 80 81 /** 82 * Constant for no line ending. 83 */ 84 public static final String LE_NONE = "None"; 85 86 /** 87 * Constant for a butt line ending. 88 */ 89 public static final String LE_BUTT = "Butt"; 90 91 /** 92 * Constant for a reversed open arrow line ending. 93 */ 94 public static final String LE_R_OPEN_ARROW = "ROpenArrow"; 95 96 /** 97 * Constant for a revered closed arrow line ending. 98 */ 99 public static final String LE_R_CLOSED_ARROW = "RClosedArrow"; 100 101 /** 102 * Constant for a slash line ending. 103 */ 104 public static final String LE_SLASH = "Slash"; 105 106 /** 107 * The type of annotation. 108 */ 109 public static final String SUB_TYPE = "Line"; 110 111 /** 112 * Constructor. 113 */ 114 public PDAnnotationLine() 115 { 116 super(); 117 getDictionary().setItem( COSName.SUBTYPE, COSName.getPDFName( SUB_TYPE ) ); 118 // Dictionary value L is mandatory, fill in with arbitary value 119 setLine( new float[] { 0, 0, 0, 0 } ); 120 121 } 122 123 /** 124 * Creates a Line annotation from a COSDictionary, expected to be a correct 125 * object definition. 126 * 127 * @param field 128 * the PDF object to represent as a field. 129 */ 130 public PDAnnotationLine( COSDictionary field ) 131 { 132 super( field ); 133 } 134 135 /** 136 * This will set start and end coordinates of the line (or leader line if LL 137 * entry is set). 138 * 139 * @param l 140 * array of 4 floats [x1, y1, x2, y2] line start and end points 141 * in default user space. 142 */ 143 public void setLine( float[] l ) 144 { 145 COSArray newL = new COSArray(); 146 newL.setFloatArray( l ); 147 getDictionary().setItem( "L", newL ); 148 } 149 150 /** 151 * This will retrieve the start and end coordinates of the line (or leader 152 * line if LL entry is set). 153 * 154 * @return array of floats [x1, y1, x2, y2] line start and end points in 155 * default user space. 156 */ 157 public float[] getLine() 158 { 159 COSArray l = (COSArray) getDictionary().getDictionaryObject( "L" ); 160 return l.toFloatArray(); 161 } 162 163 /** 164 * This will set the line ending style for the start point, 165 * see the LE_ constants for the possible values. 166 * 167 * @param style The new style. 168 */ 169 public void setStartPointEndingStyle( String style ) 170 { 171 if( style == null ) 172 { 173 style = LE_NONE; 174 } 175 COSArray array = (COSArray)getDictionary().getDictionaryObject( "LE" ); 176 if( array == null ) 177 { 178 array = new COSArray(); 179 array.add( COSName.getPDFName( style ) ); 180 array.add( COSName.getPDFName( LE_NONE ) ); 181 getDictionary().setItem( "LE", array ); 182 } 183 else 184 { 185 array.setName( 0, style ); 186 } 187 } 188 189 /** 190 * This will retrieve the line ending style for the start point, 191 * possible values shown in the LE_ constants section. 192 * 193 * @return The ending style for the start point. 194 */ 195 public String getStartPointEndingStyle() 196 { 197 String retval = LE_NONE; 198 COSArray array = (COSArray)getDictionary().getDictionaryObject( "LE" ); 199 if( array != null ) 200 { 201 retval = array.getName( 0 ); 202 } 203 204 return retval; 205 } 206 207 /** 208 * This will set the line ending style for the end point, 209 * see the LE_ constants for the possible values. 210 * 211 * @param style The new style. 212 */ 213 public void setEndPointEndingStyle( String style ) 214 { 215 if( style == null ) 216 { 217 style = LE_NONE; 218 } 219 COSArray array = (COSArray)getDictionary().getDictionaryObject( "LE" ); 220 if( array == null ) 221 { 222 array = new COSArray(); 223 array.add( COSName.getPDFName( LE_NONE ) ); 224 array.add( COSName.getPDFName( style ) ); 225 getDictionary().setItem( "LE", array ); 226 } 227 else 228 { 229 array.setName( 1, style ); 230 } 231 } 232 233 /** 234 * This will retrieve the line ending style for the end point, 235 * possible values shown in the LE_ constants section. 236 * 237 * @return The ending style for the end point. 238 */ 239 public String getEndPointEndingStyle() 240 { 241 String retval = LE_NONE; 242 COSArray array = (COSArray)getDictionary().getDictionaryObject( "LE" ); 243 if( array != null ) 244 { 245 retval = array.getName( 1 ); 246 } 247 248 return retval; 249 } 250 251 /** 252 * This will set interior colour of the line endings defined in the LE 253 * entry. Colour is in DeviceRGB colourspace. 254 * 255 * @param ic 256 * colour in the DeviceRGB colourspace. 257 * 258 */ 259 public void setInteriorColour( PDGamma ic ) 260 { 261 getDictionary().setItem( "IC", ic ); 262 } 263 264 /** 265 * This will retrieve the interior colour of the line endings defined in the 266 * LE entry. Colour is in DeviceRGB colourspace. 267 * 268 * 269 * @return PDGamma object representing the colour. 270 * 271 */ 272 public PDGamma getInteriorColour() 273 { 274 275 COSArray ic = (COSArray) getDictionary().getDictionaryObject( "IC" ); 276 if (ic != null) 277 { 278 return new PDGamma( ic ); 279 } 280 else 281 { 282 return null; 283 } 284 } 285 286 /** 287 * This will set if the contents are shown as a caption to the line. 288 * 289 * @param cap 290 * Boolean value. 291 */ 292 public void setCaption( boolean cap ) 293 { 294 getDictionary().setBoolean( "Cap", cap ); 295 } 296 297 /** 298 * This will retrieve if the contents are shown as a caption or not. 299 * 300 * @return boolean if the content is shown as a caption. 301 */ 302 public boolean getCaption() 303 { 304 return getDictionary().getBoolean( "Cap", false ); 305 } 306 307 /** 308 * This will set the border style dictionary, specifying the width and dash 309 * pattern used in drawing the line. 310 * 311 * @param bs the border style dictionary to set. 312 * 313 */ 314 public void setBorderStyle( PDBorderStyleDictionary bs ) 315 { 316 this.getDictionary().setItem( "BS", bs); 317 } 318 319 /** 320 * This will retrieve the border style dictionary, specifying the width and 321 * dash pattern used in drawing the line. 322 * 323 * @return the border style dictionary. 324 */ 325 public PDBorderStyleDictionary getBorderStyle() 326 { 327 COSDictionary bs = (COSDictionary) this.getDictionary().getItem( 328 COSName.getPDFName( "BS" ) ); 329 if (bs != null) 330 { 331 return new PDBorderStyleDictionary( bs ); 332 } 333 else 334 { 335 return null; 336 } 337 } 338 339 /** 340 * This will retrieve the length of the leader line. 341 * 342 * @return the length of the leader line 343 */ 344 public float getLeaderLineLength() 345 { 346 return this.getDictionary().getFloat("LL"); 347 } 348 349 /** 350 * This will set the length of the leader line. 351 * 352 * @param leaderLineLength length of the leader line 353 */ 354 public void setLeaderLineLength(float leaderLineLength) 355 { 356 this.getDictionary().setFloat("LL", leaderLineLength); 357 } 358 359 /** 360 * This will retrieve the length of the leader line extensions. 361 * 362 * @return the length of the leader line extensions 363 */ 364 public float getLeaderLineExtensionLength() 365 { 366 return this.getDictionary().getFloat("LLE"); 367 } 368 369 /** 370 * This will set the length of the leader line extensions. 371 * 372 * @param leaderLineExtensionLength length of the leader line extensions 373 */ 374 public void setLeaderLineExtensionLength(float leaderLineExtensionLength) 375 { 376 this.getDictionary().setFloat("LLE", leaderLineExtensionLength); 377 } 378 379 /** 380 * This will retrieve the length of the leader line offset. 381 * 382 * @return the length of the leader line offset 383 */ 384 public float getLeaderLineOffsetLength() 385 { 386 return this.getDictionary().getFloat("LLO"); 387 } 388 389 /** 390 * This will set the length of the leader line offset. 391 * 392 * @param leaderLineOffsetLength length of the leader line offset 393 */ 394 public void setLeaderLineOffsetLength(float leaderLineOffsetLength) 395 { 396 this.getDictionary().setFloat("LLO", leaderLineOffsetLength); 397 } 398 399 /** 400 * This will retrieve the caption positioning. 401 * 402 * @return the caption positioning 403 */ 404 public String getCaptionPositioning() 405 { 406 return this.getDictionary().getString("CP"); 407 } 408 409 /** 410 * This will set the caption positioning. 411 * Allowed values are: "Inline" and "Top" 412 * 413 * @param captionPositioning caption positioning 414 */ 415 public void setCaptionPositioning(String captionPositioning) 416 { 417 this.getDictionary().setString("CP", captionPositioning); 418 } 419 420 /** 421 * This will set the horizontal offset of the caption. 422 * 423 * @param offset the horizontal offset of the caption 424 */ 425 public void setCaptionHorizontalOffset( float offset ) 426 { 427 COSArray array = (COSArray)this.getDictionary().getDictionaryObject( "CO" ); 428 if( array == null ) 429 { 430 array = new COSArray(); 431 array.setFloatArray(new float[] {offset, 0.f}); 432 this.getDictionary().setItem( "CO", array ); 433 } 434 else 435 { 436 array.set(0, new COSFloat(offset) ); 437 } 438 } 439 440 /** 441 * This will retrieve the horizontal offset of the caption. 442 * 443 * @return the the horizontal offset of the caption 444 */ 445 public float getCaptionHorizontalOffset() 446 { 447 float retval = 0.f; 448 COSArray array = (COSArray)this.getDictionary().getDictionaryObject( "CO" ); 449 if( array != null ) 450 { 451 retval = array.toFloatArray()[0]; 452 } 453 454 return retval; 455 } 456 457 /** 458 * This will set the vertical offset of the caption. 459 * 460 * @param offset vertical offset of the caption 461 */ 462 public void setCaptionVerticalOffset( float offset ) 463 { 464 COSArray array = (COSArray)this.getDictionary().getDictionaryObject( "CO" ); 465 if( array == null ) 466 { 467 array = new COSArray(); 468 array.setFloatArray(new float[] {0.f, offset}); 469 this.getDictionary().setItem( "CO", array ); 470 } 471 else 472 { 473 array.set(1, new COSFloat(offset) ); 474 } 475 } 476 477 /** 478 * This will retrieve the vertical offset of the caption. 479 * 480 * @return the vertical offset of the caption 481 */ 482 public float getCaptionVerticalOffset() 483 { 484 float retval = 0.f; 485 COSArray array = (COSArray)this.getDictionary().getDictionaryObject( "CO" ); 486 if( array != null ) 487 { 488 retval = array.toFloatArray()[1]; 489 } 490 return retval; 491 } 492 493 }