1 /* 2 * Copyright 2010 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.typography.font.sfntly.table.core; 18 19 import com.google.typography.font.sfntly.data.ReadableFontData; 20 import com.google.typography.font.sfntly.data.WritableFontData; 21 import com.google.typography.font.sfntly.table.Header; 22 import com.google.typography.font.sfntly.table.Table; 23 import com.google.typography.font.sfntly.table.TableBasedTableBuilder; 24 25 import java.util.EnumSet; 26 import java.util.Iterator; 27 28 /** 29 * An OS/2 table - 'OS/2'. 30 * 31 * @author Stuart Gill 32 */ 33 public final class OS2Table extends Table { 34 35 /** 36 * Offsets to specific elements in the underlying data. These offsets are 37 * relative to the start of the table or the start of sub-blocks within the 38 * table. 39 */ 40 private enum Offset { 41 version(0), 42 xAvgCharWidth(2), 43 usWeightClass(4), 44 usWidthClass(6), 45 fsType(8), 46 ySubscriptXSize(10), 47 ySubscriptYSize(12), 48 ySubscriptXOffset(14), 49 ySubscriptYOffset(16), 50 ySuperscriptXSize(18), 51 ySuperscriptYSize(20), 52 ySuperscriptXOffset(22), 53 ySuperscriptYOffset(24), 54 yStrikeoutSize(26), 55 yStrikeoutPosition(28), 56 sFamilyClass(30), 57 panose(32), 58 panoseLength(10), // length of panose bytes 59 ulUnicodeRange1(42), 60 ulUnicodeRange2(46), 61 ulUnicodeRange3(50), 62 ulUnicodeRange4(54), 63 achVendId(58), 64 achVendIdLength(4), // length of ach vend id bytes 65 fsSelection(62), 66 usFirstCharIndex(64), 67 usLastCharIndex(66), 68 sTypoAscender(68), 69 sTypoDescender(70), 70 sTypoLineGap(72), 71 usWinAscent(74), 72 usWinDescent(76), 73 ulCodePageRange1(78), 74 ulCodePageRange2(82), 75 sxHeight(86), 76 sCapHeight(88), 77 usDefaultChar(90), 78 usBreakChar(92), 79 usMaxContext(94); 80 81 private final int offset; 82 Offset(int offset)83 private Offset(int offset) { 84 this.offset = offset; 85 } 86 } 87 OS2Table(Header header, ReadableFontData data)88 private OS2Table(Header header, ReadableFontData data) { 89 super(header, data); 90 } 91 tableVersion()92 public int tableVersion() { 93 return this.data.readUShort(Offset.version.offset); 94 } 95 xAvgCharWidth()96 public int xAvgCharWidth() { 97 return this.data.readShort(Offset.xAvgCharWidth.offset); 98 } 99 100 public enum WeightClass { 101 Thin(100), 102 ExtraLight(200), 103 UltraLight(200), 104 Light(300), 105 Normal(400), 106 Regular(400), 107 Medium(500), 108 SemiBold(600), 109 DemiBold(600), 110 Bold(700), 111 ExtraBold(800), 112 UltraBold(800), 113 Black(900), 114 Heavy(900); 115 116 private final int value; 117 WeightClass(int value)118 private WeightClass(int value) { 119 this.value = value; 120 } 121 value()122 public int value() { 123 return this.value; 124 } 125 equals(int value)126 public boolean equals(int value) { 127 return value == this.value; 128 } 129 valueOf(int value)130 public static WeightClass valueOf(int value) { 131 for (WeightClass weight : WeightClass.values()) { 132 if (weight.equals(value)) { 133 return weight; 134 } 135 } 136 return null; 137 } 138 } 139 usWeightClass()140 public int usWeightClass() { 141 return this.data.readUShort(Offset.usWeightClass.offset); 142 } 143 144 public enum WidthClass { 145 UltraCondensed(1), 146 ExtraCondensed(2), 147 Condensed(3), 148 SemiCondensed(4), 149 Medium(5), 150 Normal(5), 151 SemiExpanded(6), 152 Expanded(7), 153 ExtraExpanded(8), 154 UltraExpanded(9); 155 156 private final int value; 157 WidthClass(int value)158 private WidthClass(int value) { 159 this.value = value; 160 } 161 value()162 public int value() { 163 return this.value; 164 } 165 equals(int value)166 public boolean equals(int value) { 167 return value == this.value; 168 } 169 valueOf(int value)170 public static WeightClass valueOf(int value) { 171 for (WeightClass weight : WeightClass.values()) { 172 if (weight.equals(value)) { 173 return weight; 174 } 175 } 176 return null; 177 } 178 } 179 usWidthClass()180 public int usWidthClass() { 181 return this.data.readUShort(Offset.usWidthClass.offset); 182 } 183 184 /** 185 * Flags to indicate the embedding licensing rights for a font. 186 */ 187 public enum EmbeddingFlags { 188 Reserved0, 189 RestrictedLicenseEmbedding, 190 PreviewAndPrintEmbedding, 191 EditableEmbedding, 192 Reserved4, 193 Reserved5, 194 Reserved6, 195 Reserved7, 196 NoSubsetting, 197 BitmapEmbeddingOnly, 198 Reserved10, 199 Reserved11, 200 Reserved12, 201 Reserved13, 202 Reserved14, 203 Reserved15; 204 205 /** 206 * Returns the bit mask corresponding to this embedding flag. 207 * 208 * @return the bit mask corresponding to this embedding flag 209 */ mask()210 public int mask() { 211 return 1 << this.ordinal(); 212 } 213 214 /** 215 * Generates an EnumSet\<EmbeddingFlags\> representation of the supplied 216 * unsigned short. 217 * 218 * @param value the unsigned short 219 * @return a new EnumSet\<EmbeddingFlags\> 220 */ asSet(int value)221 public static EnumSet<EmbeddingFlags> asSet(int value) { 222 EnumSet<EmbeddingFlags> set = EnumSet.noneOf(EmbeddingFlags.class); 223 for (EmbeddingFlags flag : EmbeddingFlags.values()) { 224 if ((value & flag.mask()) == flag.mask()) { 225 set.add(flag); 226 } 227 } 228 return set; 229 } 230 231 /** 232 * Generates an unsigned short representation of the provided 233 * EnumSet\<EmbeddingFlags\>. 234 * 235 * @param flagSet the set of flags 236 * @return the unsigned short representation of the provided flagSet 237 */ asUShort(EnumSet<EmbeddingFlags> flagSet)238 public static int asUShort(EnumSet<EmbeddingFlags> flagSet) { 239 int flags = 0; 240 for (EmbeddingFlags flag : flagSet) { 241 flags |= flag.mask(); 242 } 243 return flags; 244 } 245 246 /** 247 * Takes an EnumSet\<EmbeddingFlags\> representation of the fsType and 248 * returns whether or not the fsType is Installable Embedding. The fsType is 249 * Installable Editing iff none of the fsType bits are set. 250 * 251 * @param flagSet the set of flags 252 * @return true if the font has InstallableEmbedding 253 */ isInstallableEditing(EnumSet<EmbeddingFlags> flagSet)254 public static boolean isInstallableEditing(EnumSet<EmbeddingFlags> flagSet) { 255 return flagSet.isEmpty(); 256 } 257 258 /** 259 * Takes the unsigned short representation of the fsType and returns whether 260 * or not the fsType is Installable Embedding. The fsType is Installable 261 * Editing iff none of the fsType bits are set. 262 * 263 * @param value the value to check 264 * @return true if the font has InstallableEmbedding 265 */ isInstallableEditing(int value)266 public static boolean isInstallableEditing(int value) { 267 return value == 0; 268 } 269 } 270 fsType()271 public EnumSet<EmbeddingFlags> fsType() { 272 return EmbeddingFlags.asSet(this.fsTypeAsInt()); 273 } 274 fsTypeAsInt()275 public int fsTypeAsInt() { 276 return this.data.readUShort(Offset.fsType.offset); 277 } 278 ySubscriptXSize()279 public int ySubscriptXSize() { 280 return this.data.readShort(Offset.ySubscriptXSize.offset); 281 } 282 ySubscriptYSize()283 public int ySubscriptYSize() { 284 return this.data.readShort(Offset.ySubscriptYSize.offset); 285 } 286 ySubscriptXOffset()287 public int ySubscriptXOffset() { 288 return this.data.readShort(Offset.ySubscriptXOffset.offset); 289 } 290 ySubscriptYOffset()291 public int ySubscriptYOffset() { 292 return this.data.readShort(Offset.ySubscriptYOffset.offset); 293 } 294 ySuperscriptXSize()295 public int ySuperscriptXSize() { 296 return this.data.readShort(Offset.ySuperscriptXSize.offset); 297 } 298 ySuperscriptYSize()299 public int ySuperscriptYSize() { 300 return this.data.readShort(Offset.ySuperscriptYSize.offset); 301 } 302 ySuperscriptXOffset()303 public int ySuperscriptXOffset() { 304 return this.data.readShort(Offset.ySuperscriptXOffset.offset); 305 } 306 ySuperscriptYOffset()307 public int ySuperscriptYOffset() { 308 return this.data.readShort(Offset.ySuperscriptYOffset.offset); 309 } 310 yStrikeoutSize()311 public int yStrikeoutSize() { 312 return this.data.readShort(Offset.yStrikeoutSize.offset); 313 } 314 yStrikeoutPosition()315 public int yStrikeoutPosition() { 316 return this.data.readShort(Offset.yStrikeoutPosition.offset); 317 } 318 319 // TODO(stuartg): IBM family enum? sFamilyClass()320 public int sFamilyClass() { 321 return this.data.readShort(Offset.sFamilyClass.offset); 322 } 323 324 // TODO(stuartg): panose class? individual getters for the panose values? panose()325 public byte[] panose() { 326 byte[] panose = new byte[10]; 327 this.data.readBytes(Offset.panose.offset, panose, 0, panose.length); 328 return panose; 329 } 330 ulUnicodeRange1()331 public long ulUnicodeRange1() { 332 return this.data.readULong(Offset.ulUnicodeRange1.offset); 333 } 334 ulUnicodeRange2()335 public long ulUnicodeRange2() { 336 return this.data.readULong(Offset.ulUnicodeRange2.offset); 337 } 338 ulUnicodeRange3()339 public long ulUnicodeRange3() { 340 return this.data.readULong(Offset.ulUnicodeRange3.offset); 341 } 342 ulUnicodeRange4()343 public long ulUnicodeRange4() { 344 return this.data.readULong(Offset.ulUnicodeRange4.offset); 345 } 346 347 public enum UnicodeRange { 348 // Do NOT reorder. This enum relies on the ordering of the data matching the 349 // ordinal numbers of the properties 350 BasicLatin, 351 Latin1Supplement, 352 LatinExtendedA, 353 LatinExtendedB, 354 IPAExtensions, 355 SpacingModifierLetters, 356 CombiningDiacriticalMarks, 357 GreekAndCoptic, 358 Coptic, 359 Cyrillic, 360 Armenian, 361 Hebrew, 362 Vai, 363 Arabic, 364 NKo, 365 Devanagari, 366 Bengali, 367 Gurmukhi, 368 Gujarati, 369 Oriya, 370 Tamil, 371 Telugu, 372 Kannada, 373 Malayalam, 374 Thai, 375 Lao, 376 Georgian, 377 Balinese, 378 HangulJamo, 379 LatinExtendedAdditional, 380 GreekExtended, 381 GeneralPunctuation, 382 SuperscriptsAndSubscripts, 383 CurrencySymbols, 384 NumberForms, 385 Arrows, 386 MathematicalOperators, 387 MiscTechnical, 388 ControlPictures, 389 OCR, 390 EnclosedAlphanumerics, 391 BoxDrawing, 392 BlockElements, 393 GeometricShapes, 394 MiscSymbols, 395 Dingbats, 396 CJKSymbolsAndPunctuation, 397 Hiragana, 398 Katakana, 399 Bopomofo, 400 HangulCompatibilityJamo, 401 Phagspa, 402 EnclosedCJKLettersAndMonths, 403 CJKCompatibility, 404 HangulSyllables, 405 NonPlane0, 406 Phoenician, 407 CJKUnifiedIdeographs, 408 PrivateUseAreaPlane0, 409 CJKStrokes, 410 AlphabeticPresentationForms, 411 ArabicPresentationFormsA, 412 CombiningHalfMarks, 413 VerticalForms, 414 SmallFormVariants, 415 ArabicPresentationFormsB, 416 HalfwidthAndFullwidthForms, 417 Specials, 418 Tibetan, 419 Syriac, 420 Thaana, 421 Sinhala, 422 Myanmar, 423 Ethiopic, 424 Cherokee, 425 UnifiedCanadianAboriginalSyllabics, 426 Ogham, 427 Runic, 428 Khmer, 429 Mongolian, 430 BraillePatterns, 431 YiSyllables, 432 Tagalog, 433 OldItalic, 434 Gothic, 435 Deseret, 436 MusicalSymbols, 437 MathematicalAlphanumericSymbols, 438 PrivateUsePlane15And16, 439 VariationSelectors, 440 Tags, 441 Limbu, 442 TaiLe, 443 NewTaiLue, 444 Buginese, 445 Glagolitic, 446 Tifnagh, 447 YijingHexagramSymbols, 448 SylotiNagari, 449 LinearB, 450 AncientGreekNumbers, 451 Ugaritic, 452 OldPersian, 453 Shavian, 454 Osmanya, 455 CypriotSyllabary, 456 Kharoshthi, 457 TaiXuanJingSymbols, 458 Cuneiform, 459 CountingRodNumerals, 460 Sudanese, 461 Lepcha, 462 OlChiki, 463 Saurashtra, 464 KayahLi, 465 Rejang, 466 Charm, 467 AncientSymbols, 468 PhaistosDisc, 469 Carian, 470 DominoTiles, 471 Reserved123, 472 Reserved124, 473 Reserved125, 474 Reserved126, 475 Reserved127; 476 range(int bit)477 public static UnicodeRange range(int bit) { 478 if (bit > UnicodeRange.values().length) { 479 return null; 480 } 481 return UnicodeRange.values()[bit]; 482 } 483 asSet(long range1, long range2, long range3, long range4)484 public static EnumSet<UnicodeRange> asSet(long range1, long range2, long range3, long range4) { 485 EnumSet<UnicodeRange> set = EnumSet.noneOf(UnicodeRange.class); 486 long[] range = {range1, range2, range3, range4}; 487 int rangeBit = 0; 488 int rangeIndex = -1; 489 for (UnicodeRange ur : UnicodeRange.values()) { 490 if (ur.ordinal() % 32 == 0) { 491 rangeBit = 0; 492 rangeIndex++; 493 } else { 494 rangeBit++; 495 } 496 if ((range[rangeIndex] & 1 << rangeBit) == 1 << rangeBit) { 497 set.add(ur); 498 } 499 } 500 return set; 501 } 502 asArray(EnumSet<UnicodeRange> rangeSet)503 public static long[] asArray(EnumSet<UnicodeRange> rangeSet) { 504 long[] range = new long[4]; 505 Iterator<UnicodeRange> iter = rangeSet.iterator(); 506 while (iter.hasNext()) { 507 UnicodeRange ur = iter.next(); 508 int urSegment = ur.ordinal() / 32; 509 long urFlag = 1 << (ur.ordinal() % 32); 510 range[urSegment] |= urFlag; 511 } 512 return range; 513 } 514 } 515 ulUnicodeRange()516 public EnumSet<UnicodeRange> ulUnicodeRange() { 517 return UnicodeRange.asSet( 518 this.ulUnicodeRange1(), this.ulUnicodeRange2(), 519 this.ulUnicodeRange3(), this.ulUnicodeRange4()); 520 } 521 achVendId()522 public byte[] achVendId() { 523 byte[] b = new byte[4]; 524 this.data.readBytes(Offset.achVendId.offset, b, 0, b.length); 525 return b; 526 } 527 fsSelectionAsInt()528 public int fsSelectionAsInt() { 529 return this.data.readUShort(Offset.fsSelection.offset); 530 } 531 532 public enum FsSelection { 533 ITALIC, 534 UNDERSCORE, 535 NEGATIVE, 536 OUTLINED, 537 STRIKEOUT, 538 BOLD, 539 REGULAR, 540 USE_TYPO_METRICS, 541 WWS, 542 OBLIQUE; 543 mask()544 public int mask() { 545 return 1 << this.ordinal(); 546 } 547 asSet(int value)548 public static EnumSet<FsSelection> asSet(int value) { 549 EnumSet<FsSelection> set = EnumSet.noneOf(FsSelection.class); 550 for (FsSelection selection : FsSelection.values()) { 551 if ((value & selection.mask()) == selection.mask()) { 552 set.add(selection); 553 } 554 } 555 return set; 556 } 557 asInt(EnumSet<FsSelection> fsSelectionSet)558 public static int asInt(EnumSet<FsSelection> fsSelectionSet) { 559 int value = 0; 560 Iterator<FsSelection> iter = fsSelectionSet.iterator(); 561 while (iter.hasNext()) { 562 FsSelection fsSelection = iter.next(); 563 value |= fsSelection.mask(); 564 } 565 return value; 566 } 567 } 568 fsSelection()569 public EnumSet<FsSelection> fsSelection() { 570 return FsSelection.asSet(this.fsSelectionAsInt()); 571 } 572 usFirstCharIndex()573 public int usFirstCharIndex() { 574 return this.data.readUShort(Offset.usFirstCharIndex.offset); 575 } 576 usLastCharIndex()577 public int usLastCharIndex() { 578 return this.data.readUShort(Offset.usLastCharIndex.offset); 579 } 580 sTypoAscender()581 public int sTypoAscender() { 582 return this.data.readShort(Offset.sTypoAscender.offset); 583 } 584 sTypoDescender()585 public int sTypoDescender() { 586 return this.data.readShort(Offset.sTypoDescender.offset); 587 } 588 sTypoLineGap()589 public int sTypoLineGap() { 590 return this.data.readShort(Offset.sTypoLineGap.offset); 591 } 592 usWinAscent()593 public int usWinAscent() { 594 return this.data.readUShort(Offset.usWinAscent.offset); 595 } 596 usWinDescent()597 public int usWinDescent() { 598 return this.data.readUShort(Offset.usWinDescent.offset); 599 } 600 ulCodePageRange1()601 public long ulCodePageRange1() { 602 return this.data.readULong(Offset.ulCodePageRange1.offset); 603 } 604 ulCodePageRange2()605 public long ulCodePageRange2() { 606 return this.data.readULong(Offset.ulCodePageRange2.offset); 607 } 608 609 public enum CodePageRange { 610 Latin1_1252, 611 Latin2_1250, 612 Cyrillic_1251, 613 Greek_1253, 614 Turkish_1254, 615 Hebrew_1255, 616 Arabic_1256, 617 WindowsBaltic_1257, 618 Vietnamese_1258, 619 AlternateANSI9, 620 AlternateANSI10, 621 AlternateANSI11, 622 AlternateANSI12, 623 AlternateANSI13, 624 AlternateANSI14, 625 AlternateANSI15, 626 Thai_874, 627 JapanJIS_932, 628 ChineseSimplified_936, 629 KoreanWansung_949, 630 ChineseTraditional_950, 631 KoreanJohab_1361, 632 AlternateANSI22, 633 AlternateANSI23, 634 AlternateANSI24, 635 AlternateANSI25, 636 AlternateANSI26, 637 AlternateANSI27, 638 AlternateANSI28, 639 MacintoshCharacterSet, 640 OEMCharacterSet, 641 SymbolCharacterSet, 642 ReservedForOEM32, 643 ReservedForOEM33, 644 ReservedForOEM34, 645 ReservedForOEM35, 646 ReservedForOEM36, 647 ReservedForOEM37, 648 ReservedForOEM38, 649 ReservedForOEM39, 650 ReservedForOEM40, 651 ReservedForOEM41, 652 ReservedForOEM42, 653 ReservedForOEM43, 654 ReservedForOEM44, 655 ReservedForOEM45, 656 ReservedForOEM46, 657 ReservedForOEM47, 658 IBMGreek_869, 659 MSDOSRussion_866, 660 MSDOSNordic_865, 661 Arabic_864, 662 MSDOSCanadianFrench_863, 663 Hebrew_862, 664 MSDOSIcelandic_861, 665 MSDOSPortugese_860, 666 IBMTurkish_857, 667 IBMCyrillic_855, 668 Latin2_852, 669 MSDOSBaltic_775, 670 Greek_737, 671 Arabic_708, 672 Latin1_850, 673 US_437; 674 range(int bit)675 public static UnicodeRange range(int bit) { 676 if (bit > UnicodeRange.values().length) { 677 return null; 678 } 679 return UnicodeRange.values()[bit]; 680 } 681 asSet(long range1, long range2)682 public static EnumSet<CodePageRange> asSet(long range1, long range2) { 683 EnumSet<CodePageRange> set = EnumSet.noneOf(CodePageRange.class); 684 long[] range = {range1, range2}; 685 int rangeBit = 0; 686 int rangeIndex = -1; 687 for (CodePageRange cpr : CodePageRange.values()) { 688 if (cpr.ordinal() % 32 == 0) { 689 rangeBit = 0; 690 rangeIndex++; 691 } else { 692 rangeBit++; 693 } 694 if ((range[rangeIndex] & 1 << rangeBit) == 1 << rangeBit) { 695 set.add(cpr); 696 } 697 } 698 return set; 699 } 700 asArray(EnumSet<CodePageRange> rangeSet)701 public static long[] asArray(EnumSet<CodePageRange> rangeSet) { 702 long[] range = new long[4]; 703 Iterator<CodePageRange> iter = rangeSet.iterator(); 704 while (iter.hasNext()) { 705 CodePageRange ur = iter.next(); 706 int urSegment = ur.ordinal() / 32; 707 long urFlag = 1 << (ur.ordinal() % 32); 708 range[urSegment] |= urFlag; 709 } 710 return range; 711 } 712 } 713 ulCodePageRange()714 public EnumSet<CodePageRange> ulCodePageRange() { 715 return CodePageRange.asSet(this.ulCodePageRange1(), this.ulCodePageRange1()); 716 } 717 sxHeight()718 public int sxHeight() { 719 return this.data.readShort(Offset.sxHeight.offset); 720 } 721 sCapHeight()722 public int sCapHeight() { 723 return this.data.readShort(Offset.sCapHeight.offset); 724 } 725 usDefaultChar()726 public int usDefaultChar() { 727 return this.data.readUShort(Offset.usDefaultChar.offset); 728 } 729 usBreakChar()730 public int usBreakChar() { 731 return this.data.readUShort(Offset.usBreakChar.offset); 732 } 733 usMaxContext()734 public int usMaxContext() { 735 return this.data.readUShort(Offset.usMaxContext.offset); 736 } 737 738 /** 739 * A builder for the OS/2 table = 'OS/2'. 740 * 741 */ 742 public static class Builder extends TableBasedTableBuilder<OS2Table> { 743 744 /** 745 * Create a new builder using the header information and data provided. 746 * 747 * @param header the header information 748 * @param data the data holding the table 749 * @return a new builder 750 */ createBuilder(Header header, WritableFontData data)751 public static Builder createBuilder(Header header, WritableFontData data) { 752 return new Builder(header, data); 753 } 754 Builder(Header header, WritableFontData data)755 protected Builder(Header header, WritableFontData data) { 756 super(header, data); 757 } 758 Builder(Header header, ReadableFontData data)759 protected Builder(Header header, ReadableFontData data) { 760 super(header, data); 761 } 762 763 @Override subBuildTable(ReadableFontData data)764 protected OS2Table subBuildTable(ReadableFontData data) { 765 return new OS2Table(this.header(), data); 766 } 767 tableVersion()768 public int tableVersion() { 769 return this.internalReadData().readUShort(Offset.version.offset); 770 } 771 setTableVersion(int version)772 public void setTableVersion(int version) { 773 this.internalWriteData().writeUShort(Offset.version.offset, version); 774 } 775 xAvgCharWidth()776 public int xAvgCharWidth() { 777 return this.internalReadData().readShort(Offset.xAvgCharWidth.offset); 778 } 779 setXAvgCharWidth(int width)780 public void setXAvgCharWidth(int width) { 781 this.internalWriteData().writeShort(Offset.xAvgCharWidth.offset, width); 782 } 783 usWeightClass()784 public int usWeightClass() { 785 return this.internalReadData().readUShort(Offset.usWeightClass.offset); 786 } 787 setUsWeightClass(int weight)788 public void setUsWeightClass(int weight) { 789 this.internalWriteData().writeUShort(Offset.usWeightClass.offset, weight); 790 } 791 usWidthClass()792 public int usWidthClass() { 793 return this.internalReadData().readUShort(Offset.usWidthClass.offset); 794 } 795 setUsWidthClass(int width)796 public void setUsWidthClass(int width) { 797 this.internalWriteData().writeUShort(Offset.usWidthClass.offset, width); 798 } 799 fsType()800 public EnumSet<EmbeddingFlags> fsType() { 801 return EmbeddingFlags.asSet(this.fsTypeAsInt()); 802 } 803 fsTypeAsInt()804 public int fsTypeAsInt() { 805 return this.internalReadData().readUShort(Offset.fsType.offset); 806 } 807 setFsType(EnumSet<EmbeddingFlags> flagSet)808 public void setFsType(EnumSet<EmbeddingFlags> flagSet) { 809 this.setFsType(EmbeddingFlags.asUShort(flagSet)); 810 } 811 setFsType(int fsType)812 public void setFsType(int fsType) { 813 this.internalWriteData().writeUShort(Offset.fsType.offset, fsType); 814 } 815 ySubscriptXSize()816 public int ySubscriptXSize() { 817 return this.internalReadData().readShort(Offset.ySubscriptXSize.offset); 818 } 819 setYSubscriptXSize(int size)820 public void setYSubscriptXSize(int size) { 821 this.internalWriteData().writeShort(Offset.ySubscriptXSize.offset, size); 822 } 823 ySubscriptYSize()824 public int ySubscriptYSize() { 825 return this.internalReadData().readShort(Offset.ySubscriptYSize.offset); 826 } 827 setYSubscriptYSize(int size)828 public void setYSubscriptYSize(int size) { 829 this.internalWriteData().writeShort(Offset.ySubscriptYSize.offset, size); 830 } 831 ySubscriptXOffset()832 public int ySubscriptXOffset() { 833 return this.internalReadData().readShort(Offset.ySubscriptXOffset.offset); 834 } 835 setYSubscriptXOffset(int offset)836 public void setYSubscriptXOffset(int offset) { 837 this.internalWriteData().writeShort(Offset.ySubscriptXOffset.offset, offset); 838 } 839 ySubscriptYOffset()840 public int ySubscriptYOffset() { 841 return this.internalReadData().readShort(Offset.ySubscriptYOffset.offset); 842 } 843 setYSubscriptYOffset(int offset)844 public void setYSubscriptYOffset(int offset) { 845 this.internalWriteData().writeShort(Offset.ySubscriptYOffset.offset, offset); 846 } 847 ySuperscriptXSize()848 public int ySuperscriptXSize() { 849 return this.internalReadData().readShort(Offset.ySuperscriptXSize.offset); 850 } 851 setYSuperscriptXSize(int size)852 public void setYSuperscriptXSize(int size) { 853 this.internalWriteData().writeShort(Offset.ySuperscriptXSize.offset, size); 854 } 855 ySuperscriptYSize()856 public int ySuperscriptYSize() { 857 return this.internalReadData().readShort(Offset.ySuperscriptYSize.offset); 858 } 859 setYSuperscriptYSize(int size)860 public void setYSuperscriptYSize(int size) { 861 this.internalWriteData().writeShort(Offset.ySuperscriptYSize.offset, size); 862 } 863 ySuperscriptXOffset()864 public int ySuperscriptXOffset() { 865 return this.internalReadData().readShort(Offset.ySuperscriptXOffset.offset); 866 } 867 setYSuperscriptXOffset(int offset)868 public void setYSuperscriptXOffset(int offset) { 869 this.internalWriteData().writeShort(Offset.ySuperscriptXOffset.offset, offset); 870 } 871 ySuperscriptYOffset()872 public int ySuperscriptYOffset() { 873 return this.internalReadData().readShort(Offset.ySuperscriptYOffset.offset); 874 } 875 setYSuperscriptYOffset(int offset)876 public void setYSuperscriptYOffset(int offset) { 877 this.internalWriteData().writeShort(Offset.ySuperscriptYOffset.offset, offset); 878 } 879 yStrikeoutSize()880 public int yStrikeoutSize() { 881 return this.internalReadData().readShort(Offset.yStrikeoutSize.offset); 882 } 883 setYStrikeoutSize(int size)884 public void setYStrikeoutSize(int size) { 885 this.internalWriteData().writeShort(Offset.yStrikeoutSize.offset, size); 886 } 887 yStrikeoutPosition()888 public int yStrikeoutPosition() { 889 return this.internalReadData().readShort(Offset.yStrikeoutPosition.offset); 890 } 891 setYStrikeoutPosition(int position)892 public void setYStrikeoutPosition(int position) { 893 this.internalWriteData().writeShort(Offset.yStrikeoutPosition.offset, position); 894 } 895 sFamilyClass()896 public int sFamilyClass() { 897 return this.internalReadData().readShort(Offset.sFamilyClass.offset); 898 } 899 setSFamilyClass(int family)900 public void setSFamilyClass(int family) { 901 this.internalWriteData().writeShort(Offset.sFamilyClass.offset, family); 902 } 903 panose()904 public byte[] panose() { 905 byte[] panose = new byte[Offset.panoseLength.offset]; 906 this.internalReadData().readBytes(Offset.panose.offset, panose, 0, panose.length); 907 return panose; 908 } 909 setPanose(byte[] panose)910 public void setPanose(byte[] panose) { 911 if (panose.length != Offset.panoseLength.offset) { 912 throw new IllegalArgumentException("Panose bytes must be exactly 10 in length."); 913 } 914 this.internalWriteData().writeBytes(Offset.panose.offset, panose, 0, panose.length); 915 } 916 ulUnicodeRange1()917 public long ulUnicodeRange1() { 918 return this.internalReadData().readULong(Offset.ulUnicodeRange1.offset); 919 } 920 setUlUnicodeRange1(long range)921 public void setUlUnicodeRange1(long range) { 922 this.internalWriteData().writeULong(Offset.ulUnicodeRange1.offset, range); 923 } 924 ulUnicodeRange2()925 public long ulUnicodeRange2() { 926 return this.internalReadData().readULong(Offset.ulUnicodeRange2.offset); 927 } 928 setUlUnicodeRange2(long range)929 public void setUlUnicodeRange2(long range) { 930 this.internalWriteData().writeULong(Offset.ulUnicodeRange2.offset, range); 931 } 932 ulUnicodeRange3()933 public long ulUnicodeRange3() { 934 return this.internalReadData().readULong(Offset.ulUnicodeRange3.offset); 935 } 936 setUlUnicodeRange3(long range)937 public void setUlUnicodeRange3(long range) { 938 this.internalWriteData().writeULong(Offset.ulUnicodeRange3.offset, range); 939 } 940 ulUnicodeRange4()941 public long ulUnicodeRange4() { 942 return this.internalReadData().readULong(Offset.ulUnicodeRange4.offset); 943 } 944 setUlUnicodeRange4(long range)945 public void setUlUnicodeRange4(long range) { 946 this.internalWriteData().writeULong(Offset.ulUnicodeRange4.offset, range); 947 } 948 ulUnicodeRange()949 public EnumSet<UnicodeRange> ulUnicodeRange() { 950 return UnicodeRange.asSet(this.ulUnicodeRange1(), this.ulUnicodeRange2(), 951 this.ulUnicodeRange3(), this.ulUnicodeRange4()); 952 } 953 setUlUnicodeRange(EnumSet<UnicodeRange> rangeSet)954 public void setUlUnicodeRange(EnumSet<UnicodeRange> rangeSet) { 955 long[] range = UnicodeRange.asArray(rangeSet); 956 this.setUlUnicodeRange1(range[0]); 957 this.setUlUnicodeRange2(range[1]); 958 this.setUlUnicodeRange3(range[2]); 959 this.setUlUnicodeRange4(range[3]); 960 } 961 achVendId()962 public byte[] achVendId() { 963 byte[] b = new byte[Offset.achVendIdLength.offset]; 964 this.internalReadData().readBytes(Offset.achVendId.offset, b, 0, b.length); 965 return b; 966 } 967 968 /** 969 * Sets the achVendId field. 970 * 971 * This field is 4 bytes in length and only the first 4 bytes of the byte 972 * array will be written. If the byte array is less than 4 bytes it will be 973 * padded out with space characters (0x20). 974 * 975 * @param b ach Vendor Id 976 */ setAchVendId(byte[] b)977 public void setAchVendId(byte[] b) { 978 this.internalWriteData().writeBytesPad( 979 Offset.achVendId.offset, b, 0, Offset.achVendIdLength.offset, (byte) ' '); 980 } 981 fsSelectionAsInt()982 public int fsSelectionAsInt() { 983 return this.internalReadData().readUShort(Offset.fsSelection.offset); 984 } 985 setFsSelection(int fsSelection)986 public void setFsSelection(int fsSelection) { 987 this.internalWriteData().writeUShort(Offset.fsSelection.offset, fsSelection); 988 } 989 fsSelection(EnumSet<FsSelection> fsSelection)990 public void fsSelection(EnumSet<FsSelection> fsSelection) { 991 this.setFsSelection(FsSelection.asInt(fsSelection)); 992 } 993 usFirstCharIndex()994 public int usFirstCharIndex() { 995 return this.internalReadData().readUShort(Offset.usFirstCharIndex.offset); 996 } 997 setUsFirstCharIndex(int firstIndex)998 public void setUsFirstCharIndex(int firstIndex) { 999 this.internalWriteData().writeUShort(Offset.usFirstCharIndex.offset, firstIndex); 1000 } 1001 usLastCharIndex()1002 public int usLastCharIndex() { 1003 return this.internalReadData().readUShort(Offset.usLastCharIndex.offset); 1004 } 1005 setUsLastCharIndex(int lastIndex)1006 public void setUsLastCharIndex(int lastIndex) { 1007 this.internalWriteData().writeUShort(Offset.usLastCharIndex.offset, lastIndex); 1008 } 1009 sTypoAscender()1010 public int sTypoAscender() { 1011 return this.internalReadData().readShort(Offset.sTypoAscender.offset); 1012 } 1013 setSTypoAscender(int ascender)1014 public void setSTypoAscender(int ascender) { 1015 this.internalWriteData().writeShort(Offset.sTypoAscender.offset, ascender); 1016 } 1017 sTypoDescender()1018 public int sTypoDescender() { 1019 return this.internalReadData().readShort(Offset.sTypoDescender.offset); 1020 } 1021 setSTypoDescender(int descender)1022 public void setSTypoDescender(int descender) { 1023 this.internalWriteData().writeShort(Offset.sTypoDescender.offset, descender); 1024 } 1025 sTypoLineGap()1026 public int sTypoLineGap() { 1027 return this.internalReadData().readShort(Offset.sTypoLineGap.offset); 1028 } 1029 setSTypoLineGap(int lineGap)1030 public void setSTypoLineGap(int lineGap) { 1031 this.internalWriteData().writeShort(Offset.sTypoLineGap.offset, lineGap); 1032 } 1033 usWinAscent()1034 public int usWinAscent() { 1035 return this.internalReadData().readUShort(Offset.usWinAscent.offset); 1036 } 1037 setUsWinAscent(int ascent)1038 public void setUsWinAscent(int ascent) { 1039 this.internalWriteData().writeUShort(Offset.usWinAscent.offset, ascent); 1040 } 1041 usWinDescent()1042 public int usWinDescent() { 1043 return this.internalReadData().readUShort(Offset.usWinDescent.offset); 1044 } 1045 setUsWinDescent(int descent)1046 public void setUsWinDescent(int descent) { 1047 this.internalWriteData().writeUShort(Offset.usWinAscent.offset, descent); 1048 } 1049 ulCodePageRange1()1050 public long ulCodePageRange1() { 1051 return this.internalReadData().readULong(Offset.ulCodePageRange1.offset); 1052 } 1053 setUlCodePageRange1(long range)1054 public void setUlCodePageRange1(long range) { 1055 this.internalWriteData().writeULong(Offset.ulCodePageRange1.offset, range); 1056 } 1057 ulCodePageRange2()1058 public long ulCodePageRange2() { 1059 return this.internalReadData().readULong(Offset.ulCodePageRange2.offset); 1060 } 1061 setUlCodePageRange2(long range)1062 public void setUlCodePageRange2(long range) { 1063 this.internalWriteData().writeULong(Offset.ulCodePageRange2.offset, range); 1064 } 1065 ulCodePageRange()1066 public EnumSet<CodePageRange> ulCodePageRange() { 1067 return CodePageRange.asSet(this.ulCodePageRange1(), this.ulCodePageRange2()); 1068 } 1069 setUlCodePageRange(EnumSet<CodePageRange> rangeSet)1070 public void setUlCodePageRange(EnumSet<CodePageRange> rangeSet) { 1071 long[] range = CodePageRange.asArray(rangeSet); 1072 this.setUlCodePageRange1(range[0]); 1073 this.setUlCodePageRange2(range[1]); 1074 } 1075 sxHeight()1076 public int sxHeight() { 1077 return this.internalReadData().readShort(Offset.sxHeight.offset); 1078 } 1079 setSxHeight(int height)1080 public void setSxHeight(int height) { 1081 this.internalWriteData().writeShort(Offset.sxHeight.offset, height); 1082 } 1083 sCapHeight()1084 public int sCapHeight() { 1085 return this.internalReadData().readShort(Offset.sCapHeight.offset); 1086 } 1087 setSCapHeight(int height)1088 public void setSCapHeight(int height) { 1089 this.internalWriteData().writeShort(Offset.sCapHeight.offset, height); 1090 } 1091 usDefaultChar()1092 public int usDefaultChar() { 1093 return this.internalReadData().readUShort(Offset.usDefaultChar.offset); 1094 } 1095 setUsDefaultChar(int defaultChar)1096 public void setUsDefaultChar(int defaultChar) { 1097 this.internalWriteData().writeUShort(Offset.usDefaultChar.offset, defaultChar); 1098 } 1099 usBreakChar()1100 public int usBreakChar() { 1101 return this.internalReadData().readUShort(Offset.usBreakChar.offset); 1102 } 1103 setUsBreakChar(int breakChar)1104 public void setUsBreakChar(int breakChar) { 1105 this.internalWriteData().writeUShort(Offset.usBreakChar.offset, breakChar); 1106 } 1107 usMaxContext()1108 public int usMaxContext() { 1109 return this.internalReadData().readUShort(Offset.usMaxContext.offset); 1110 } 1111 setUsMaxContext(int maxContext)1112 public void setUsMaxContext(int maxContext) { 1113 this.internalWriteData().writeUShort(Offset.usMaxContext.offset, maxContext); 1114 } 1115 } 1116 } 1117