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.fontbox.afm; 18 19 import java.io.IOException; 20 21 import java.util.ArrayList; 22 import java.util.HashMap; 23 import java.util.Iterator; 24 import java.util.List; 25 import java.util.Map; 26 27 import org.apache.fontbox.util.BoundingBox; 28 29 /** 30 * This is the outermost AFM type. This can be created by the afmparser with a valid 31 * AFM document. 32 * 33 * @author Ben Litchfield (ben@benlitchfield.com) 34 * @version $Revision: 1.3 $ 35 */ 36 public class FontMetric 37 { 38 /** 39 * This is the version of the FontMetrics. 40 */ 41 private float afmVersion; 42 private int metricSets = 0; 43 private String fontName; 44 private String fullName; 45 private String familyName; 46 private String weight; 47 private BoundingBox fontBBox; 48 private String fontVersion; 49 private String notice; 50 private String encodingScheme; 51 private int mappingScheme; 52 private int escChar; 53 private String characterSet; 54 private int characters; 55 private boolean isBaseFont; 56 private float[] vVector; 57 private boolean isFixedV; 58 private float capHeight; 59 private float xHeight; 60 private float ascender; 61 private float descender; 62 private List<String> comments = new ArrayList<String>(); 63 64 private float underlinePosition; 65 private float underlineThickness; 66 private float italicAngle; 67 private float[] charWidth; 68 private boolean isFixedPitch; 69 private float standardHorizontalWidth; 70 private float standardVerticalWidth; 71 72 private List<CharMetric> charMetrics = new ArrayList<CharMetric>(); 73 private Map<String,CharMetric> charMetricsMap = new HashMap<String,CharMetric>(); 74 private List<TrackKern> trackKern = new ArrayList<TrackKern>(); 75 private List<Composite> composites = new ArrayList<Composite>(); 76 private List<KernPair> kernPairs = new ArrayList<KernPair>(); 77 private List<KernPair> kernPairs0 = new ArrayList<KernPair>(); 78 private List<KernPair> kernPairs1 = new ArrayList<KernPair>(); 79 80 /** 81 * Constructor. 82 */ 83 public FontMetric() 84 { 85 } 86 87 /** 88 * This will get the width of a character. 89 * 90 * @param name The character to get the width for. 91 * 92 * @return The width of the character. 93 * 94 * @throws IOException If this AFM file does not handle the character. 95 */ 96 public float getCharacterWidth( String name ) throws IOException 97 { 98 float result = 0; 99 CharMetric metric = charMetricsMap.get( name ); 100 if( metric == null ) 101 { 102 result=0; 103 //don't throw an exception right away. 104 //throw new IOException( "Unknown AFM(" + getFullName() + ") characer '" + name + "'" ); 105 } 106 else 107 { 108 result = metric.getWx(); 109 } 110 return result; 111 } 112 113 /** 114 * This will get the width of a character. 115 * 116 * @param name The character to get the width for. 117 * 118 * @return The width of the character. 119 * 120 * @throws IOException If this AFM file does not handle the character. 121 */ 122 public float getCharacterHeight( String name ) throws IOException 123 { 124 float result = 0; 125 CharMetric metric = charMetricsMap.get( name ); 126 if( metric == null ) 127 { 128 result=0; 129 //don't throw an exception right away. 130 //throw new IOException( "Unknown AFM(" + getFullName() + ") characer '" + name + "'" ); 131 } 132 else 133 { 134 if( metric.getWy() == 0 ) 135 { 136 result = metric.getBoundingBox().getHeight(); 137 } 138 else 139 { 140 result = metric.getWy(); 141 } 142 } 143 return result; 144 } 145 146 147 /** 148 * This will get the average width of a character. 149 * 150 * @return The width of the character. 151 * 152 * @throws IOException If this AFM file does not handle the character. 153 */ 154 public float getAverageCharacterWidth() throws IOException 155 { 156 float average = 0; 157 float totalWidths = 0; 158 float characterCount = 0; 159 Iterator<CharMetric> iter = charMetricsMap.values().iterator(); 160 while( iter.hasNext() ) 161 { 162 CharMetric metric = iter.next(); 163 if( metric.getWx() > 0 ) 164 { 165 totalWidths += metric.getWx(); 166 characterCount += 1; 167 } 168 } 169 if( totalWidths > 0 ) 170 { 171 average = totalWidths / characterCount; 172 } 173 174 return average; 175 } 176 177 /** 178 * This will add a new comment. 179 * 180 * @param comment The comment to add to this metric. 181 */ 182 public void addComment( String comment ) 183 { 184 comments.add( comment ); 185 } 186 187 /** 188 * This will get all comments. 189 * 190 * @return The list of all comments. 191 */ 192 public List<String> getComments() 193 { 194 return comments; 195 } 196 197 /** 198 * This will get the version of the AFM document. 199 * 200 * @return The version of the document. 201 */ 202 public float getAFMVersion() 203 { 204 return afmVersion; 205 } 206 207 /** 208 * This will get the metricSets attribute. 209 * 210 * @return The value of the metric sets. 211 */ 212 public int getMetricSets() 213 { 214 return metricSets; 215 } 216 217 /** 218 * This will set the version of the AFM document. 219 * 220 * @param afmVersionValue The version of the document. 221 */ 222 public void setAFMVersion( float afmVersionValue ) 223 { 224 afmVersion = afmVersionValue; 225 } 226 227 /** 228 * This will set the metricSets attribute. This value must be 0,1, or 2. 229 * 230 * @param metricSetsValue The new metric sets attribute. 231 */ 232 public void setMetricSets( int metricSetsValue ) 233 { 234 if( metricSetsValue < 0 || metricSetsValue > 2 ) 235 { 236 throw new RuntimeException( "The metricSets attribute must be in the " + 237 "set {0,1,2} and not '" + metricSetsValue + "'" ); 238 } 239 metricSets = metricSetsValue; 240 } 241 242 /** 243 * Getter for property fontName. 244 * 245 * @return Value of property fontName. 246 */ 247 public String getFontName() 248 { 249 return fontName; 250 } 251 252 /** 253 * Setter for property fontName. 254 * 255 * @param name New value of property fontName. 256 */ 257 public void setFontName(String name) 258 { 259 fontName = name; 260 } 261 262 /** 263 * Getter for property fullName. 264 * 265 * @return Value of property fullName. 266 */ 267 public String getFullName() 268 { 269 return fullName; 270 } 271 272 /** 273 * Setter for property fullName. 274 * 275 * @param fullNameValue New value of property fullName. 276 */ 277 public void setFullName(String fullNameValue) 278 { 279 fullName = fullNameValue; 280 } 281 282 /** 283 * Getter for property familyName. 284 * 285 * @return Value of property familyName. 286 */ 287 public String getFamilyName() 288 { 289 return familyName; 290 } 291 292 /** 293 * Setter for property familyName. 294 * 295 * @param familyNameValue New value of property familyName. 296 */ 297 public void setFamilyName(String familyNameValue) 298 { 299 familyName = familyNameValue; 300 } 301 302 /** 303 * Getter for property weight. 304 * 305 * @return Value of property weight. 306 */ 307 public String getWeight() 308 { 309 return weight; 310 } 311 312 /** 313 * Setter for property weight. 314 * 315 * @param weightValue New value of property weight. 316 */ 317 public void setWeight(String weightValue) 318 { 319 weight = weightValue; 320 } 321 322 /** 323 * Getter for property fontBBox. 324 * 325 * @return Value of property fontBBox. 326 */ 327 public BoundingBox getFontBBox() 328 { 329 return fontBBox; 330 } 331 332 /** 333 * Setter for property fontBBox. 334 * 335 * @param bBox New value of property fontBBox. 336 */ 337 public void setFontBBox(BoundingBox bBox) 338 { 339 this.fontBBox = bBox; 340 } 341 342 /** 343 * Getter for property notice. 344 * 345 * @return Value of property notice. 346 */ 347 public String getNotice() 348 { 349 return notice; 350 } 351 352 /** 353 * Setter for property notice. 354 * 355 * @param noticeValue New value of property notice. 356 */ 357 public void setNotice(String noticeValue) 358 { 359 notice = noticeValue; 360 } 361 362 /** 363 * Getter for property encodingScheme. 364 * 365 * @return Value of property encodingScheme. 366 */ 367 public String getEncodingScheme() 368 { 369 return encodingScheme; 370 } 371 372 /** 373 * Setter for property encodingScheme. 374 * 375 * @param encodingSchemeValue New value of property encodingScheme. 376 */ 377 public void setEncodingScheme(String encodingSchemeValue) 378 { 379 encodingScheme = encodingSchemeValue; 380 } 381 382 /** 383 * Getter for property mappingScheme. 384 * 385 * @return Value of property mappingScheme. 386 */ 387 public int getMappingScheme() 388 { 389 return mappingScheme; 390 } 391 392 /** 393 * Setter for property mappingScheme. 394 * 395 * @param mappingSchemeValue New value of property mappingScheme. 396 */ 397 public void setMappingScheme(int mappingSchemeValue) 398 { 399 mappingScheme = mappingSchemeValue; 400 } 401 402 /** 403 * Getter for property escChar. 404 * 405 * @return Value of property escChar. 406 */ 407 public int getEscChar() 408 { 409 return escChar; 410 } 411 412 /** 413 * Setter for property escChar. 414 * 415 * @param escCharValue New value of property escChar. 416 */ 417 public void setEscChar(int escCharValue) 418 { 419 escChar = escCharValue; 420 } 421 422 /** 423 * Getter for property characterSet. 424 * 425 * @return Value of property characterSet. 426 */ 427 public String getCharacterSet() 428 { 429 return characterSet; 430 } 431 432 /** 433 * Setter for property characterSet. 434 * 435 * @param characterSetValue New value of property characterSet. 436 */ 437 public void setCharacterSet(String characterSetValue) 438 { 439 characterSet = characterSetValue; 440 } 441 442 /** 443 * Getter for property characters. 444 * 445 * @return Value of property characters. 446 */ 447 public int getCharacters() 448 { 449 return characters; 450 } 451 452 /** 453 * Setter for property characters. 454 * 455 * @param charactersValue New value of property characters. 456 */ 457 public void setCharacters(int charactersValue) 458 { 459 characters = charactersValue; 460 } 461 462 /** 463 * Getter for property isBaseFont. 464 * 465 * @return Value of property isBaseFont. 466 */ 467 public boolean isBaseFont() 468 { 469 return isBaseFont; 470 } 471 472 /** 473 * Setter for property isBaseFont. 474 * 475 * @param isBaseFontValue New value of property isBaseFont. 476 */ 477 public void setIsBaseFont(boolean isBaseFontValue) 478 { 479 isBaseFont = isBaseFontValue; 480 } 481 482 /** 483 * Getter for property vVector. 484 * 485 * @return Value of property vVector. 486 */ 487 public float[] getVVector() 488 { 489 return this.vVector; 490 } 491 492 /** 493 * Setter for property vVector. 494 * 495 * @param vVectorValue New value of property vVector. 496 */ 497 public void setVVector(float[] vVectorValue) 498 { 499 vVector = vVectorValue; 500 } 501 502 /** 503 * Getter for property isFixedV. 504 * 505 * @return Value of property isFixedV. 506 */ 507 public boolean isFixedV() 508 { 509 return isFixedV; 510 } 511 512 /** 513 * Setter for property isFixedV. 514 * 515 * @param isFixedVValue New value of property isFixedV. 516 */ 517 public void setIsFixedV(boolean isFixedVValue) 518 { 519 isFixedV = isFixedVValue; 520 } 521 522 /** 523 * Getter for property capHeight. 524 * 525 * @return Value of property capHeight. 526 */ 527 public float getCapHeight() 528 { 529 return capHeight; 530 } 531 532 /** 533 * Setter for property capHeight. 534 * 535 * @param capHeightValue New value of property capHeight. 536 */ 537 public void setCapHeight(float capHeightValue) 538 { 539 capHeight = capHeightValue; 540 } 541 542 /** 543 * Getter for property xHeight. 544 * 545 * @return Value of property xHeight. 546 */ 547 public float getXHeight() 548 { 549 return xHeight; 550 } 551 552 /** 553 * Setter for property xHeight. 554 * 555 * @param xHeightValue New value of property xHeight. 556 */ 557 public void setXHeight( float xHeightValue ) 558 { 559 xHeight = xHeightValue; 560 } 561 562 /** 563 * Getter for property ascender. 564 * 565 * @return Value of property ascender. 566 */ 567 public float getAscender() 568 { 569 return ascender; 570 } 571 572 /** 573 * Setter for property ascender. 574 * 575 * @param ascenderValue New value of property ascender. 576 */ 577 public void setAscender( float ascenderValue ) 578 { 579 ascender = ascenderValue; 580 } 581 582 /** 583 * Getter for property descender. 584 * 585 * @return Value of property descender. 586 */ 587 public float getDescender() 588 { 589 return descender; 590 } 591 592 /** 593 * Setter for property descender. 594 * 595 * @param descenderValue New value of property descender. 596 */ 597 public void setDescender( float descenderValue ) 598 { 599 descender = descenderValue; 600 } 601 602 /** 603 * Getter for property fontVersion. 604 * 605 * @return Value of property fontVersion. 606 */ 607 public String getFontVersion() 608 { 609 return fontVersion; 610 } 611 612 /** 613 * Setter for property fontVersion. 614 * 615 * @param fontVersionValue New value of property fontVersion. 616 */ 617 public void setFontVersion(String fontVersionValue) 618 { 619 fontVersion = fontVersionValue; 620 } 621 622 /** 623 * Getter for property underlinePosition. 624 * 625 * @return Value of property underlinePosition. 626 */ 627 public float getUnderlinePosition() 628 { 629 return underlinePosition; 630 } 631 632 /** 633 * Setter for property underlinePosition. 634 * 635 * @param underlinePositionValue New value of property underlinePosition. 636 */ 637 public void setUnderlinePosition(float underlinePositionValue) 638 { 639 underlinePosition = underlinePositionValue; 640 } 641 642 /** 643 * Getter for property underlineThickness. 644 * 645 * @return Value of property underlineThickness. 646 */ 647 public float getUnderlineThickness() 648 { 649 return underlineThickness; 650 } 651 652 /** 653 * Setter for property underlineThickness. 654 * 655 * @param underlineThicknessValue New value of property underlineThickness. 656 */ 657 public void setUnderlineThickness(float underlineThicknessValue) 658 { 659 underlineThickness = underlineThicknessValue; 660 } 661 662 /** 663 * Getter for property italicAngle. 664 * 665 * @return Value of property italicAngle. 666 */ 667 public float getItalicAngle() 668 { 669 return italicAngle; 670 } 671 672 /** 673 * Setter for property italicAngle. 674 * 675 * @param italicAngleValue New value of property italicAngle. 676 */ 677 public void setItalicAngle(float italicAngleValue) 678 { 679 italicAngle = italicAngleValue; 680 } 681 682 /** 683 * Getter for property charWidth. 684 * 685 * @return Value of property charWidth. 686 */ 687 public float[] getCharWidth() 688 { 689 return this.charWidth; 690 } 691 692 /** 693 * Setter for property charWidth. 694 * 695 * @param charWidthValue New value of property charWidth. 696 */ 697 public void setCharWidth(float[] charWidthValue) 698 { 699 charWidth = charWidthValue; 700 } 701 702 /** 703 * Getter for property isFixedPitch. 704 * 705 * @return Value of property isFixedPitch. 706 */ 707 public boolean isFixedPitch() 708 { 709 return isFixedPitch; 710 } 711 712 /** 713 * Setter for property isFixedPitch. 714 * 715 * @param isFixedPitchValue New value of property isFixedPitch. 716 */ 717 public void setFixedPitch(boolean isFixedPitchValue) 718 { 719 isFixedPitch = isFixedPitchValue; 720 } 721 722 /** Getter for property charMetrics. 723 * @return Value of property charMetrics. 724 */ 725 public List<CharMetric> getCharMetrics() 726 { 727 return charMetrics; 728 } 729 730 /** Setter for property charMetrics. 731 * @param charMetricsValue New value of property charMetrics. 732 */ 733 public void setCharMetrics(List<CharMetric> charMetricsValue) 734 { 735 charMetrics = charMetricsValue; 736 } 737 738 /** 739 * This will add another character metric. 740 * 741 * @param metric The character metric to add. 742 */ 743 public void addCharMetric( CharMetric metric ) 744 { 745 charMetrics.add( metric ); 746 charMetricsMap.put( metric.getName(), metric ); 747 } 748 749 /** Getter for property trackKern. 750 * @return Value of property trackKern. 751 */ 752 public List<TrackKern> getTrackKern() 753 { 754 return trackKern; 755 } 756 757 /** Setter for property trackKern. 758 * @param trackKernValue New value of property trackKern. 759 */ 760 public void setTrackKern(List<TrackKern> trackKernValue) 761 { 762 trackKern = trackKernValue; 763 } 764 765 /** 766 * This will add another track kern. 767 * 768 * @param kern The track kerning data. 769 */ 770 public void addTrackKern( TrackKern kern ) 771 { 772 trackKern.add( kern ); 773 } 774 775 /** Getter for property composites. 776 * @return Value of property composites. 777 */ 778 public List<Composite> getComposites() 779 { 780 return composites; 781 } 782 783 /** Setter for property composites. 784 * @param compositesList New value of property composites. 785 */ 786 public void setComposites(List<Composite> compositesList) 787 { 788 composites = compositesList; 789 } 790 791 /** 792 * This will add a single composite part to the picture. 793 * 794 * @param composite The composite info to add. 795 */ 796 public void addComposite( Composite composite ) 797 { 798 composites.add( composite ); 799 } 800 801 /** Getter for property kernPairs. 802 * @return Value of property kernPairs. 803 */ 804 public List<KernPair> getKernPairs() 805 { 806 return kernPairs; 807 } 808 809 /** 810 * This will add a kern pair. 811 * 812 * @param kernPair The kern pair to add. 813 */ 814 public void addKernPair( KernPair kernPair ) 815 { 816 kernPairs.add( kernPair ); 817 } 818 819 /** Setter for property kernPairs. 820 * @param kernPairsList New value of property kernPairs. 821 */ 822 public void setKernPairs(List<KernPair> kernPairsList) 823 { 824 kernPairs = kernPairsList; 825 } 826 827 /** Getter for property kernPairs0. 828 * @return Value of property kernPairs0. 829 */ 830 public List<KernPair> getKernPairs0() 831 { 832 return kernPairs0; 833 } 834 835 /** 836 * This will add a kern pair. 837 * 838 * @param kernPair The kern pair to add. 839 */ 840 public void addKernPair0( KernPair kernPair ) 841 { 842 kernPairs0.add( kernPair ); 843 } 844 845 /** Setter for property kernPairs0. 846 * @param kernPairs0List New value of property kernPairs0. 847 */ 848 public void setKernPairs0(List<KernPair> kernPairs0List) 849 { 850 kernPairs0 = kernPairs0List; 851 } 852 853 /** Getter for property kernPairs1. 854 * @return Value of property kernPairs1. 855 */ 856 public List<KernPair> getKernPairs1() 857 { 858 return kernPairs1; 859 } 860 861 /** 862 * This will add a kern pair. 863 * 864 * @param kernPair The kern pair to add. 865 */ 866 public void addKernPair1( KernPair kernPair ) 867 { 868 kernPairs1.add( kernPair ); 869 } 870 871 /** Setter for property kernPairs1. 872 * @param kernPairs1List New value of property kernPairs1. 873 */ 874 public void setKernPairs1(List<KernPair> kernPairs1List) 875 { 876 kernPairs1 = kernPairs1List; 877 } 878 879 /** Getter for property standardHorizontalWidth. 880 * @return Value of property standardHorizontalWidth. 881 */ 882 public float getStandardHorizontalWidth() 883 { 884 return standardHorizontalWidth; 885 } 886 887 /** Setter for property standardHorizontalWidth. 888 * @param standardHorizontalWidthValue New value of property standardHorizontalWidth. 889 */ 890 public void setStandardHorizontalWidth(float standardHorizontalWidthValue) 891 { 892 standardHorizontalWidth = standardHorizontalWidthValue; 893 } 894 895 /** Getter for property standardVerticalWidth. 896 * @return Value of property standardVerticalWidth. 897 */ 898 public float getStandardVerticalWidth() 899 { 900 return standardVerticalWidth; 901 } 902 903 /** Setter for property standardVerticalWidth. 904 * @param standardVerticalWidthValue New value of property standardVerticalWidth. 905 */ 906 public void setStandardVerticalWidth(float standardVerticalWidthValue) 907 { 908 standardVerticalWidth = standardVerticalWidthValue; 909 } 910 911 }