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.font; 18 19 import org.apache.pdfbox.cos.COSArray; 20 import org.apache.pdfbox.cos.COSBase; 21 import org.apache.pdfbox.cos.COSDictionary; 22 import org.apache.pdfbox.cos.COSName; 23 import org.apache.pdfbox.cos.COSString; 24 import org.apache.pdfbox.cos.COSStream; 25 26 import org.apache.pdfbox.pdmodel.common.COSObjectable; 27 import org.apache.pdfbox.pdmodel.common.PDRectangle; 28 import org.apache.pdfbox.pdmodel.common.PDStream; 29 30 /** 31 * This class represents an implementation to the font descriptor that gets its 32 * information from a COS Dictionary. 33 * 34 * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a> 35 * @version $Revision: 1.4 $ 36 */ 37 public class PDFontDescriptorDictionary extends PDFontDescriptor implements COSObjectable 38 { 39 private COSDictionary dic; 40 41 /** 42 * Constructor. 43 */ 44 public PDFontDescriptorDictionary() 45 { 46 dic = new COSDictionary(); 47 dic.setName( "Type", "FontDescriptor" ); 48 } 49 50 /** 51 * Constructor. 52 * 53 * @param desc The wrapped COS Dictionary. 54 */ 55 public PDFontDescriptorDictionary( COSDictionary desc ) 56 { 57 dic = desc; 58 } 59 60 /** 61 * This will get the dictionary for this object. 62 * 63 * @return The COS dictionary. 64 */ 65 public COSDictionary getCOSDictionary() 66 { 67 return dic; 68 } 69 70 /** 71 * Convert this standard java object to a COS object. 72 * 73 * @return The cos object that matches this Java object. 74 */ 75 public COSBase getCOSObject() 76 { 77 return dic; 78 } 79 80 /** 81 * Get the font name. 82 * 83 * @return The name of the font. 84 */ 85 public String getFontName() 86 { 87 String retval = null; 88 COSName name = (COSName)dic.getDictionaryObject( COSName.FONT_NAME ); 89 if( name != null ) 90 { 91 retval = name.getName(); 92 } 93 return retval; 94 } 95 96 /** 97 * This will set the font name. 98 * 99 * @param fontName The new name for the font. 100 */ 101 public void setFontName( String fontName ) 102 { 103 COSName name = null; 104 if( fontName != null ) 105 { 106 name = COSName.getPDFName( fontName ); 107 } 108 dic.setItem( COSName.FONT_NAME, name ); 109 } 110 111 /** 112 * A string representing the preferred font family. 113 * 114 * @return The font family. 115 */ 116 public String getFontFamily() 117 { 118 String retval = null; 119 COSString name = (COSString)dic.getDictionaryObject( COSName.FONT_FAMILY ); 120 if( name != null ) 121 { 122 retval = name.getString(); 123 } 124 return retval; 125 } 126 127 /** 128 * This will set the font family. 129 * 130 * @param fontFamily The font family. 131 */ 132 public void setFontFamily( String fontFamily ) 133 { 134 COSString name = null; 135 if( fontFamily != null ) 136 { 137 name = new COSString( fontFamily ); 138 } 139 dic.setItem( COSName.FONT_FAMILY, name ); 140 } 141 142 /** 143 * The weight of the font. According to the PDF spec "possible values are 144 * 100, 200, 300, 400, 500, 600, 700, 800 or 900" Where a higher number is 145 * more weight and appears to be more bold. 146 * 147 * @return The font weight. 148 */ 149 public float getFontWeight() 150 { 151 return dic.getFloat( "FontWeight",0 ); 152 } 153 154 /** 155 * Set the weight of the font. 156 * 157 * @param fontWeight The new weight of the font. 158 */ 159 public void setFontWeight( float fontWeight ) 160 { 161 dic.setFloat( "FontWeight", fontWeight ); 162 } 163 164 /** 165 * A string representing the preferred font stretch. 166 * According to the PDF Spec: 167 * The font stretch value; it must be one of the following (ordered from 168 * narrowest to widest): UltraCondensed, ExtraCondensed, Condensed, SemiCondensed, 169 * Normal, SemiExpanded, Expanded, ExtraExpanded or UltraExpanded. 170 * 171 * @return The stretch of the font. 172 */ 173 public String getFontStretch() 174 { 175 String retval = null; 176 COSName name = (COSName)dic.getDictionaryObject( COSName.FONT_STRETCH ); 177 if( name != null ) 178 { 179 retval = name.getName(); 180 } 181 return retval; 182 } 183 184 /** 185 * This will set the font stretch. 186 * 187 * @param fontStretch The new stretch for the font. 188 */ 189 public void setFontStretch( String fontStretch ) 190 { 191 COSName name = null; 192 if( fontStretch != null ) 193 { 194 name = COSName.getPDFName( fontStretch ); 195 } 196 dic.setItem( COSName.FONT_STRETCH, name ); 197 } 198 199 /** 200 * This will get the font flags. 201 * 202 * @return The font flags. 203 */ 204 public int getFlags() 205 { 206 return dic.getInt( "Flags", 0 ); 207 } 208 209 /** 210 * This will set the font flags. 211 * 212 * @param flags The new font flags. 213 */ 214 public void setFlags( int flags ) 215 { 216 dic.setInt( "Flags", flags ); 217 } 218 219 /** 220 * This will get the fonts bouding box. 221 * 222 * @return The fonts bouding box. 223 */ 224 public PDRectangle getFontBoundingBox() 225 { 226 COSArray rect = (COSArray)dic.getDictionaryObject( COSName.FONT_BBOX ); 227 PDRectangle retval = null; 228 if( rect != null ) 229 { 230 retval = new PDRectangle( rect ); 231 } 232 return retval; 233 } 234 235 /** 236 * Set the fonts bounding box. 237 * 238 * @param rect The new bouding box. 239 */ 240 public void setFontBoundingBox( PDRectangle rect ) 241 { 242 COSArray array = null; 243 if( rect != null ) 244 { 245 array = rect.getCOSArray(); 246 } 247 dic.setItem( COSName.FONT_BBOX, array ); 248 } 249 250 /** 251 * This will get the italic angle for the font. 252 * 253 * @return The italic angle. 254 */ 255 public float getItalicAngle() 256 { 257 return dic.getFloat( "ItalicAngle", 0 ); 258 } 259 260 /** 261 * This will set the italic angle for the font. 262 * 263 * @param angle The new italic angle for the font. 264 */ 265 public void setItalicAngle( float angle ) 266 { 267 dic.setFloat( "ItalicAngle", angle ); 268 } 269 270 /** 271 * This will get the ascent for the font. 272 * 273 * @return The ascent. 274 */ 275 public float getAscent() 276 { 277 return dic.getFloat( "Ascent", 0 ); 278 } 279 280 /** 281 * This will set the ascent for the font. 282 * 283 * @param ascent The new ascent for the font. 284 */ 285 public void setAscent( float ascent ) 286 { 287 dic.setFloat( "Ascent", ascent ); 288 } 289 290 /** 291 * This will get the descent for the font. 292 * 293 * @return The descent. 294 */ 295 public float getDescent() 296 { 297 return dic.getFloat( "Descent", 0 ); 298 } 299 300 /** 301 * This will set the descent for the font. 302 * 303 * @param descent The new descent for the font. 304 */ 305 public void setDescent( float descent ) 306 { 307 dic.setFloat( "Descent", descent ); 308 } 309 310 /** 311 * This will get the leading for the font. 312 * 313 * @return The leading. 314 */ 315 public float getLeading() 316 { 317 return dic.getFloat( "Leading", 0 ); 318 } 319 320 /** 321 * This will set the leading for the font. 322 * 323 * @param leading The new leading for the font. 324 */ 325 public void setLeading( float leading ) 326 { 327 dic.setFloat( "Leading", leading ); 328 } 329 330 /** 331 * This will get the CapHeight for the font. 332 * 333 * @return The cap height. 334 */ 335 public float getCapHeight() 336 { 337 if(capHeight==Float.NEGATIVE_INFINITY){ 338 /* We observed a negative value being returned with 339 * the Scheherazade font. PDFBOX-429 was logged for this. 340 * We are not sure if returning the absolute value 341 * is the correct fix, but it seems to work. */ 342 capHeight = java.lang.Math.abs(dic.getFloat( "CapHeight", 0 )); 343 } 344 return capHeight; 345 } 346 347 private float capHeight = Float.NEGATIVE_INFINITY; 348 349 /** 350 * This will set the cap height for the font. 351 * 352 * @param capHeight The new cap height for the font. 353 */ 354 public void setCapHeight( float capHeight ) 355 { 356 dic.setFloat( "CapHeight", capHeight ); 357 this.capHeight = capHeight; 358 } 359 360 /** 361 * This will get the x height for the font. 362 * 363 * @return The x height. 364 */ 365 public float getXHeight() 366 { 367 if(xHeight==Float.NEGATIVE_INFINITY){ 368 /* We observed a negative value being returned with 369 * the Scheherazade font. PDFBOX-429 was logged for this. 370 * We are not sure if returning the absolute value 371 * is the correct fix, but it seems to work. */ 372 xHeight = java.lang.Math.abs(dic.getFloat( "XHeight", 0 )); 373 } 374 return xHeight; 375 } 376 377 private float xHeight = Float.NEGATIVE_INFINITY; 378 379 /** 380 * This will set the x height for the font. 381 * 382 * @param xHeight The new x height for the font. 383 */ 384 public void setXHeight( float xHeight ) 385 { 386 dic.setFloat( "XHeight", xHeight ); 387 this.xHeight = xHeight; 388 } 389 390 /** 391 * This will get the stemV for the font. 392 * 393 * @return The stem v value. 394 */ 395 public float getStemV() 396 { 397 return dic.getFloat( "StemV", 0 ); 398 } 399 400 /** 401 * This will set the stem V for the font. 402 * 403 * @param stemV The new stem v for the font. 404 */ 405 public void setStemV( float stemV ) 406 { 407 dic.setFloat( "StemV", stemV ); 408 } 409 410 /** 411 * This will get the stemH for the font. 412 * 413 * @return The stem h value. 414 */ 415 public float getStemH() 416 { 417 return dic.getFloat( "StemH", 0 ); 418 } 419 420 /** 421 * This will set the stem H for the font. 422 * 423 * @param stemH The new stem h for the font. 424 */ 425 public void setStemH( float stemH ) 426 { 427 dic.setFloat( "StemH", stemH ); 428 } 429 430 /** 431 * This will get the average width for the font. 432 * 433 * @return The average width value. 434 */ 435 public float getAverageWidth() 436 { 437 return dic.getFloat( "AvgWidth", 0 ); 438 } 439 440 /** 441 * This will set the average width for the font. 442 * 443 * @param averageWidth The new average width for the font. 444 */ 445 public void setAverageWidth( float averageWidth ) 446 { 447 dic.setFloat( "AvgWidth", averageWidth ); 448 } 449 450 /** 451 * This will get the max width for the font. 452 * 453 * @return The max width value. 454 */ 455 public float getMaxWidth() 456 { 457 return dic.getFloat( "MaxWidth", 0 ); 458 } 459 460 /** 461 * This will set the max width for the font. 462 * 463 * @param maxWidth The new max width for the font. 464 */ 465 public void setMaxWidth( float maxWidth ) 466 { 467 dic.setFloat( "MaxWidth", maxWidth ); 468 } 469 470 /** 471 * This will get the missing width for the font. 472 * 473 * @return The missing width value. 474 */ 475 public float getMissingWidth() 476 { 477 return dic.getFloat( "MissingWidth", 0 ); 478 } 479 480 /** 481 * This will set the missing width for the font. 482 * 483 * @param missingWidth The new missing width for the font. 484 */ 485 public void setMissingWidth( float missingWidth ) 486 { 487 dic.setFloat( "MissingWidth", missingWidth ); 488 } 489 490 /** 491 * This will get the character set for the font. 492 * 493 * @return The character set value. 494 */ 495 public String getCharSet() 496 { 497 String retval = null; 498 COSString name = (COSString)dic.getDictionaryObject( COSName.CHAR_SET ); 499 if( name != null ) 500 { 501 retval = name.getString(); 502 } 503 return retval; 504 } 505 506 /** 507 * This will set the character set for the font. 508 * 509 * @param charSet The new character set for the font. 510 */ 511 public void setCharacterSet( String charSet ) 512 { 513 COSString name = null; 514 if( charSet != null ) 515 { 516 name = new COSString( charSet ); 517 } 518 dic.setItem( COSName.CHAR_SET, name ); 519 } 520 521 /** 522 * A stream containing a Type 1 font program. 523 * 524 * @return A stream containing a Type 1 font program. 525 */ 526 public PDStream getFontFile() 527 { 528 PDStream retval = null; 529 COSStream stream = (COSStream)dic.getDictionaryObject( "FontFile" ); 530 if( stream != null ) 531 { 532 retval = new PDStream( stream ); 533 } 534 return retval; 535 } 536 537 /** 538 * Set the type 1 font program. 539 * 540 * @param type1Stream The type 1 stream. 541 */ 542 public void setFontFile( PDStream type1Stream ) 543 { 544 dic.setItem( "FontFile", type1Stream ); 545 } 546 547 /** 548 * A stream containing a true type font program. 549 * 550 * @return A stream containing a true type font program. 551 */ 552 public PDStream getFontFile2() 553 { 554 PDStream retval = null; 555 COSStream stream = (COSStream)dic.getDictionaryObject( "FontFile2" ); 556 if( stream != null ) 557 { 558 retval = new PDStream( stream ); 559 } 560 return retval; 561 } 562 563 /** 564 * Set the true type font program. 565 * 566 * @param ttfStream The true type stream. 567 */ 568 public void setFontFile2( PDStream ttfStream ) 569 { 570 dic.setItem( "FontFile2", ttfStream ); 571 } 572 573 /** 574 * A stream containing a font program that is not true type or type 1. 575 * 576 * @return A stream containing a font program. 577 */ 578 public PDStream getFontFile3() 579 { 580 PDStream retval = null; 581 COSStream stream = (COSStream)dic.getDictionaryObject( "FontFile3" ); 582 if( stream != null ) 583 { 584 retval = new PDStream( stream ); 585 } 586 return retval; 587 } 588 589 /** 590 * Set a stream containing a font program that is not true type or type 1. 591 * 592 * @param stream The font program stream. 593 */ 594 public void setFontFile3( PDStream stream ) 595 { 596 dic.setItem( "FontFile3", stream ); 597 } 598 }