• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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