Browse Source

Directly use FOP fonts to lay out SVG images for PDF, PS and AFP outputs.

The metrics are now taken from FOP configured fonts and no longer from AWT equivalents. That avoids discrepancies in case AWT and FOP use slightly different fonts, or if the font is not installed on the system. That actually also avoids having to install the font on the system.
FOP is also used for the primary layout of text (prior to SVG-specific transforms like translation or rotation) for consistency between SVG and XSL-FO.
This is a joint work from Peter Hancock and myself.


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_FopFontsForSVG@1508208 13f79535-47bb-0310-9956-ffa450edef68
pull/22/head
Vincent Hennebert 10 years ago
parent
commit
74dd94b26c
100 changed files with 7129 additions and 5089 deletions
  1. 6
    1
      build.xml
  2. 30
    0
      findbugs-exclude.xml
  3. BIN
      lib/batik-all-1.7.jar
  4. BIN
      lib/batik-all-trunk-patch1041.jar
  5. 236
    265
      src/codegen/fonts/Courier.xml
  6. 236
    265
      src/codegen/fonts/CourierBold.xml
  7. 235
    264
      src/codegen/fonts/CourierBoldOblique.xml
  8. 236
    265
      src/codegen/fonts/CourierOblique.xml
  9. 233
    232
      src/codegen/fonts/Helvetica.xml
  10. 233
    232
      src/codegen/fonts/HelveticaBold.xml
  11. 233
    232
      src/codegen/fonts/HelveticaBoldOblique.xml
  12. 234
    233
      src/codegen/fonts/HelveticaOblique.xml
  13. 194
    193
      src/codegen/fonts/Symbol.xml
  14. 233
    232
      src/codegen/fonts/TimesBold.xml
  15. 233
    232
      src/codegen/fonts/TimesBoldItalic.xml
  16. 234
    233
      src/codegen/fonts/TimesItalic.xml
  17. 233
    232
      src/codegen/fonts/TimesRoman.xml
  18. 207
    205
      src/codegen/fonts/ZapfDingbats.xml
  19. 23
    3
      src/codegen/fonts/font-file.xsl
  20. 8
    0
      src/java/org/apache/fop/afp/AFPEventProducer.java
  21. 31
    1
      src/java/org/apache/fop/afp/fonts/AFPFont.java
  22. 11
    49
      src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
  23. 27
    45
      src/java/org/apache/fop/afp/fonts/CharacterSet.java
  24. 41
    54
      src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
  25. 66
    58
      src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
  26. 31
    3
      src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
  27. 19
    31
      src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
  28. 71
    0
      src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java
  29. 16
    0
      src/java/org/apache/fop/afp/fonts/OutlineFont.java
  30. 32
    56
      src/java/org/apache/fop/afp/fonts/RasterFont.java
  31. 5
    1
      src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
  32. 18
    24
      src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
  33. 84
    0
      src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java
  34. 11
    20
      src/java/org/apache/fop/afp/svg/AFPTextHandler.java
  35. 19
    2
      src/java/org/apache/fop/afp/svg/AFPTextPainter.java
  36. 2
    92
      src/java/org/apache/fop/fo/FOText.java
  37. 11
    0
      src/java/org/apache/fop/fonts/Base14Font.java
  38. 1
    0
      src/java/org/apache/fop/fonts/CIDFont.java
  39. 47
    0
      src/java/org/apache/fop/fonts/CustomFont.java
  40. 14
    23
      src/java/org/apache/fop/fonts/FontInfo.java
  41. 44
    0
      src/java/org/apache/fop/fonts/FontMetrics.java
  42. 327
    0
      src/java/org/apache/fop/fonts/GlyphMapping.java
  43. 26
    0
      src/java/org/apache/fop/fonts/LazyFont.java
  44. 18
    0
      src/java/org/apache/fop/fonts/MultiByteFont.java
  45. 37
    3
      src/java/org/apache/fop/fonts/SingleByteFont.java
  46. 31
    0
      src/java/org/apache/fop/fonts/TextFragment.java
  47. 36
    2
      src/java/org/apache/fop/fonts/truetype/TTFFile.java
  48. 14
    6
      src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
  49. 4
    4
      src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java
  50. 12
    5
      src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
  51. 3
    4
      src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java
  52. 2
    1
      src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java
  53. 232
    487
      src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
  54. 3
    1
      src/java/org/apache/fop/render/AbstractGenericSVGHandler.java
  55. 8
    7
      src/java/org/apache/fop/render/afp/AFPSVGHandler.java
  56. 21
    0
      src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
  57. 20
    0
      src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java
  58. 3
    2
      src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java
  59. 21
    0
      src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java
  60. 3
    1
      src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
  61. 3
    0
      src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java
  62. 3
    2
      src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java
  63. 1
    2
      src/java/org/apache/fop/render/ps/PSSVGHandler.java
  64. 132
    229
      src/java/org/apache/fop/render/ps/PSTextPainter.java
  65. 20
    48
      src/java/org/apache/fop/svg/ACIUtils.java
  66. 92
    239
      src/java/org/apache/fop/svg/AbstractFOPTextPainter.java
  67. 15
    7
      src/java/org/apache/fop/svg/AbstractFOPTranscoder.java
  68. 132
    15
      src/java/org/apache/fop/svg/NativeTextPainter.java
  69. 84
    145
      src/java/org/apache/fop/svg/PDFTextPainter.java
  70. 0
    41
      src/java/org/apache/fop/svg/PDFTextUtil.java
  71. 4
    2
      src/java/org/apache/fop/svg/PDFTranscoder.java
  72. 7
    4
      src/java/org/apache/fop/svg/SVGUserAgent.java
  73. 11
    1
      src/java/org/apache/fop/svg/SimpleSVGUserAgent.java
  74. 70
    0
      src/java/org/apache/fop/svg/font/AggregatingFontFamilyResolver.java
  75. 31
    0
      src/java/org/apache/fop/svg/font/FOPFontFamilyResolver.java
  76. 67
    0
      src/java/org/apache/fop/svg/font/FOPFontFamilyResolverImpl.java
  77. 159
    0
      src/java/org/apache/fop/svg/font/FOPGVTFont.java
  78. 73
    0
      src/java/org/apache/fop/svg/font/FOPGVTFontFamily.java
  79. 339
    0
      src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java
  80. 47
    0
      src/java/org/apache/fop/svg/font/FilteringFontFamilyResolver.java
  81. 48
    0
      test/java/org/apache/fop/afp/fonts/IntegerKeyStoreTestCase.java
  82. 15
    2
      test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java
  83. 0
    9
      test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java
  84. 0
    37
      test/java/org/apache/fop/fonts/svg-fonts.fo
  85. 20
    2
      test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java
  86. 12
    3
      test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java
  87. 4
    0
      test/java/org/apache/fop/fonts/type1/underline.afm
  88. 78
    0
      test/java/org/apache/fop/svg/NativeTextPainterTest.java
  89. 108
    0
      test/java/org/apache/fop/svg/OperatorValidator.java
  90. 149
    0
      test/java/org/apache/fop/svg/PDFTextPainterTestCase.java
  91. 77
    0
      test/java/org/apache/fop/svg/PSTextPainterTestCase.java
  92. 9
    0
      test/java/org/apache/fop/svg/baseline-shift.svg
  93. 8
    0
      test/java/org/apache/fop/svg/dx-dy.svg
  94. 193
    0
      test/java/org/apache/fop/svg/font/BasicGlyphVectorTestCase.java
  95. 127
    0
      test/java/org/apache/fop/svg/font/FOPFontFamilyResolverTestCase.java
  96. 72
    0
      test/java/org/apache/fop/svg/font/FOPGVTFontTestCase.java
  97. 27
    0
      test/java/org/apache/fop/svg/font/FOPGVTGlyphVectorTest.java
  98. 102
    0
      test/java/org/apache/fop/svg/font/FontInfoBuilder.java
  99. 91
    0
      test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java
  100. 0
    0
      test/java/org/apache/fop/svg/glyph-orientation.svg

+ 6
- 1
build.xml View File

@@ -565,11 +565,13 @@ list of possible build targets.
<include name="org/apache/fop/apps/io/**"/>
<include name="org/apache/fop/complexscripts/fonts/*.class"/>
<include name="org/apache/fop/complexscripts/util/GlyphTester.class"/>
<include name="org/apache/fop/events/EventProducer.class"/>
<include name="org/apache/fop/fo/Constants.class"/>
<include name="org/apache/fop/fo/FOTreeBuilder.class"/>
<include name="org/apache/fop/area/AreaTreeControl*"/>
<include name="org/apache/fop/svg/**"/>
<include name="org/apache/fop/fonts/**"/>
<include name="org/apache/fop/traits/MinOptMax.class"/>
<include name="org/apache/fop/image/loader/batik/BatikImageFlavors*.class"/>
<include name="org/apache/fop/util/CMYKColorSpace*.class"/>
<include name="org/apache/fop/util/Color*.class"/>
@@ -579,6 +581,7 @@ list of possible build targets.
<include name="org/apache/fop/util/Finalizable.class"/>
<include name="org/apache/fop/util/CharUtilities.class"/>
<include name="org/apache/fop/util/DecimalFormatCache*.class"/>
<include name="org/apache/fop/util/ImageObject.class"/>
</patternset>
<!-- PDF transcoder -->
<patternset>
@@ -647,7 +650,8 @@ list of possible build targets.
<include name="org/apache/xmlgraphics/java2d/**"/>
<include name="org/apache/xmlgraphics/ps/**"/>
<include name="org/apache/xmlgraphics/fonts/**"/>
<include name="org/apache/xmlgraphics/util/io/**"/>
<include name="org/apache/xmlgraphics/util/**"/>
<include name="org/apache/xmlgraphics/image/loader/**"/>
</patternset>
<fileset refid="transcoder-lib-files"/>
</unjar>
@@ -709,6 +713,7 @@ list of possible build targets.
<include name="**/*.txt"/>
<include name="**/*.afm"/>
<include name="**/*.fo"/>
<include name="**/*.svg"/>
</fileset>
</copy>
</target>

+ 30
- 0
findbugs-exclude.xml View File

@@ -1,5 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<FindBugsFilter>
<Match>
<Class name="org.apache.fop.layoutmgr.inline.TextLayoutManager$TextAreaBuilder"/>
<Method name="getMappingBidiLevels"/>
<Bug pattern="PZLA_PREFER_ZERO_LENGTH_ARRAYS"/>
</Match>
<Match>
<Class name="org.apache.fop.svg.PDFTextPainter"/>
<Field name="pdf"/>
<Bug pattern="UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR"/>
</Match>
<Match>
<Class name="org.apache.fop.render.ps.PSTextPainter"/>
<Or>
<Field name="gen"/>
<Field name="ps"/>
<Field name="psRun"/>
<Field name="textUtil"/>
</Or>
<Bug pattern="UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.GlyphMapping"/>
<Method name="&lt;init&gt;"/>
<Bug pattern="EI_EXPOSE_REP2"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.MultiByteFont"/>
<Method name="setBBoxArray"/>
<Bug pattern="EI_EXPOSE_REP2"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile$1"/>
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON"/>

BIN
lib/batik-all-1.7.jar View File


BIN
lib/batik-all-trunk-patch1041.jar View File


+ 236
- 265
src/codegen/fonts/Courier.xml View File

@@ -22,275 +22,246 @@
<family-name>Courier</family-name>
<class-name>Courier</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>562</cap-height>
<x-height>426</x-height>
<ascender>629</ascender>
<descender>-157</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="600"/>
<char name="AE" width="600"/>
<char name="Aacute" width="600"/>
<char name="Acircumflex" width="600"/>
<char name="Adieresis" width="600"/>
<char name="Agrave" width="600"/>
<char name="Aring" width="600"/>
<char name="Atilde" width="600"/>
<char name="B" width="600"/>
<char name="C" width="600"/>
<char name="Ccedilla" width="600"/>
<char name="D" width="600"/>
<char name="E" width="600"/>
<char name="Eacute" width="600"/>
<char name="Ecircumflex" width="600"/>
<char name="Edieresis" width="600"/>
<char name="Egrave" width="600"/>
<char name="Eth" width="600"/>
<char name="Euro" width="600"/>
<char name="F" width="600"/>
<char name="G" width="600"/>
<char name="Gcaron" width="600"/>
<char name="H" width="600"/>
<char name="I" width="600"/>
<char name="IJ" width="600"/>
<char name="Iacute" width="600"/>
<char name="Icircumflex" width="600"/>
<char name="Idieresis" width="600"/>
<char name="Idot" width="600"/>
<char name="Igrave" width="600"/>
<char name="J" width="600"/>
<char name="K" width="600"/>
<char name="L" width="600"/>
<char name="LL" width="600"/>
<char name="Lslash" width="600"/>
<char name="M" width="600"/>
<char name="N" width="600"/>
<char name="Ntilde" width="600"/>
<char name="O" width="600"/>
<char name="OE" width="600"/>
<char name="Oacute" width="600"/>
<char name="Ocircumflex" width="600"/>
<char name="Odieresis" width="600"/>
<char name="Ograve" width="600"/>
<char name="Oslash" width="600"/>
<char name="Otilde" width="600"/>
<char name="P" width="600"/>
<char name="Q" width="600"/>
<char name="R" width="600"/>
<char name="S" width="600"/>
<char name="Scaron" width="600"/>
<char name="Scedilla" width="600"/>
<char name="T" width="600"/>
<char name="Thorn" width="600"/>
<char name="U" width="600"/>
<char name="Uacute" width="600"/>
<char name="Ucircumflex" width="600"/>
<char name="Udieresis" width="600"/>
<char name="Ugrave" width="600"/>
<char name="V" width="600"/>
<char name="W" width="600"/>
<char name="X" width="600"/>
<char name="Y" width="600"/>
<char name="Yacute" width="600"/>
<char name="Ydieresis" width="600"/>
<char name="Z" width="600"/>
<char name="Zcaron" width="600"/>
<char name="a" width="600"/>
<char name="aacute" width="600"/>
<char name="acircumflex" width="600"/>
<char name="acute" width="600"/>
<char name="adieresis" width="600"/>
<char name="ae" width="600"/>
<char name="agrave" width="600"/>
<char name="ampersand" width="600"/>
<char name="aring" width="600"/>
<char name="arrowboth" width="600"/>
<char name="arrowdown" width="600"/>
<char name="arrowleft" width="600"/>
<char name="arrowright" width="600"/>
<char name="arrowup" width="600"/>
<char name="asciicircum" width="600"/>
<char name="asciitilde" width="600"/>
<char name="asterisk" width="600"/>
<char name="at" width="600"/>
<char name="atilde" width="600"/>
<char name="b" width="600"/>
<char name="backslash" width="600"/>
<char name="bar" width="600"/>
<char name="braceleft" width="600"/>
<char name="braceright" width="600"/>
<char name="bracketleft" width="600"/>
<char name="bracketright" width="600"/>
<char name="breve" width="600"/>
<char name="brokenbar" width="600"/>
<char name="bullet" width="600"/>
<char name="c" width="600"/>
<char name="caron" width="600"/>
<char name="ccedilla" width="600"/>
<char name="cedilla" width="600"/>
<char name="cent" width="600"/>
<char name="center" width="600"/>
<char name="circumflex" width="600"/>
<char name="colon" width="600"/>
<char name="comma" width="600"/>
<char name="copyright" width="600"/>
<char name="currency" width="600"/>
<char name="d" width="600"/>
<char name="dagger" width="600"/>
<char name="daggerdbl" width="600"/>
<char name="dectab" width="600"/>
<char name="degree" width="600"/>
<char name="dieresis" width="600"/>
<char name="divide" width="600"/>
<char name="dollar" width="600"/>
<char name="dotaccent" width="600"/>
<char name="dotlessi" width="600"/>
<char name="down" width="600"/>
<char name="e" width="600"/>
<char name="eacute" width="600"/>
<char name="ecircumflex" width="600"/>
<char name="edieresis" width="600"/>
<char name="egrave" width="600"/>
<char name="eight" width="600"/>
<char name="ellipsis" width="600"/>
<char name="emdash" width="600"/>
<char name="endash" width="600"/>
<char name="equal" width="600"/>
<char name="eth" width="600"/>
<char name="exclam" width="600"/>
<char name="exclamdown" width="600"/>
<char name="f" width="600"/>
<char name="fi" width="600"/>
<char name="five" width="600"/>
<char name="fl" width="600"/>
<char name="florin" width="600"/>
<char name="format" width="600"/>
<char name="four" width="600"/>
<char name="fraction" width="600"/>
<char name="g" width="600"/>
<char name="gcaron" width="600"/>
<char name="germandbls" width="600"/>
<char name="grave" width="600"/>
<char name="graybox" width="600"/>
<char name="greater" width="600"/>
<char name="guillemotleft" width="600"/>
<char name="guillemotright" width="600"/>
<char name="guilsinglleft" width="600"/>
<char name="guilsinglright" width="600"/>
<char name="h" width="600"/>
<char name="hungarumlaut" width="600"/>
<char name="hyphen" width="600"/>
<char name="i" width="600"/>
<char name="iacute" width="600"/>
<char name="icircumflex" width="600"/>
<char name="idieresis" width="600"/>
<char name="igrave" width="600"/>
<char name="ij" width="600"/>
<char name="indent" width="600"/>
<char name="j" width="600"/>
<char name="k" width="600"/>
<char name="l" width="600"/>
<char name="largebullet" width="600"/>
<char name="left" width="600"/>
<char name="less" width="600"/>
<char name="lira" width="600"/>
<char name="ll" width="600"/>
<char name="logicalnot" width="600"/>
<char name="lslash" width="600"/>
<char name="m" width="600"/>
<char name="macron" width="600"/>
<char name="merge" width="600"/>
<char name="minus" width="600"/>
<char name="mu" width="600"/>
<char name="multiply" width="600"/>
<char name="n" width="600"/>
<char name="nine" width="600"/>
<char name="notegraphic" width="600"/>
<char name="ntilde" width="600"/>
<char name="numbersign" width="600"/>
<char name="o" width="600"/>
<char name="oacute" width="600"/>
<char name="ocircumflex" width="600"/>
<char name="odieresis" width="600"/>
<char name="oe" width="600"/>
<char name="ogonek" width="600"/>
<char name="ograve" width="600"/>
<char name="one" width="600"/>
<char name="onehalf" width="600"/>
<char name="onequarter" width="600"/>
<char name="onesuperior" width="600"/>
<char name="ordfeminine" width="600"/>
<char name="ordmasculine" width="600"/>
<char name="oslash" width="600"/>
<char name="otilde" width="600"/>
<char name="overscore" width="600"/>
<char name="p" width="600"/>
<char name="paragraph" width="600"/>
<char name="parenleft" width="600"/>
<char name="parenright" width="600"/>
<char name="percent" width="600"/>
<char name="period" width="600"/>
<char name="periodcentered" width="600"/>
<char name="perthousand" width="600"/>
<char name="plus" width="600"/>
<char name="plusminus" width="600"/>
<char name="prescription" width="600"/>
<char name="q" width="600"/>
<char name="question" width="600"/>
<char name="questiondown" width="600"/>
<char name="quotedbl" width="600"/>
<char name="quotedblbase" width="600"/>
<char name="quotedblleft" width="600"/>
<char name="quotedblright" width="600"/>
<char name="quoteleft" width="600"/>
<char name="quoteright" width="600"/>
<char name="quotesinglbase" width="600"/>
<char name="quotesingle" width="600"/>
<char name="r" width="600"/>
<char name="registered" width="600"/>
<char name="return" width="600"/>
<char name="ring" width="600"/>
<char name="s" width="600"/>
<char name="scaron" width="600"/>
<char name="scedilla" width="600"/>
<char name="section" width="600"/>
<char name="semicolon" width="600"/>
<char name="seven" width="600"/>
<char name="six" width="600"/>
<char name="slash" width="600"/>
<char name="space" width="600"/>
<char-metrics>
<char name="A" width="600" llx="3" lly="0" urx="597" ury="562"/>
<char name="AE" width="600" llx="3" lly="0" urx="550" ury="562"/>
<char name="Aacute" width="600" llx="3" lly="0" urx="597" ury="805"/>
<char name="Acircumflex" width="600" llx="3" lly="0" urx="597" ury="787"/>
<char name="Adieresis" width="600" llx="3" lly="0" urx="597" ury="753"/>
<char name="Agrave" width="600" llx="3" lly="0" urx="597" ury="805"/>
<char name="Aring" width="600" llx="3" lly="0" urx="597" ury="750"/>
<char name="Atilde" width="600" llx="3" lly="0" urx="597" ury="729"/>
<char name="B" width="600" llx="43" lly="0" urx="559" ury="562"/>
<char name="C" width="600" llx="41" lly="-18" urx="540" ury="580"/>
<char name="Ccedilla" width="600" llx="41" lly="-151" urx="540" ury="580"/>
<char name="D" width="600" llx="43" lly="0" urx="574" ury="562"/>
<char name="E" width="600" llx="53" lly="0" urx="550" ury="562"/>
<char name="Eacute" width="600" llx="53" lly="0" urx="550" ury="805"/>
<char name="Ecircumflex" width="600" llx="53" lly="0" urx="550" ury="787"/>
<char name="Edieresis" width="600" llx="53" lly="0" urx="550" ury="753"/>
<char name="Egrave" width="600" llx="53" lly="0" urx="550" ury="805"/>
<char name="Eth" width="600" llx="30" lly="0" urx="574" ury="562"/>
<char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="600" llx="53" lly="0" urx="545" ury="562"/>
<char name="G" width="600" llx="31" lly="-18" urx="575" ury="580"/>
<char name="H" width="600" llx="32" lly="0" urx="568" ury="562"/>
<char name="I" width="600" llx="96" lly="0" urx="504" ury="562"/>
<char name="Iacute" width="600" llx="96" lly="0" urx="504" ury="805"/>
<char name="Icircumflex" width="600" llx="96" lly="0" urx="504" ury="787"/>
<char name="Idieresis" width="600" llx="96" lly="0" urx="504" ury="753"/>
<char name="Igrave" width="600" llx="96" lly="0" urx="504" ury="805"/>
<char name="J" width="600" llx="34" lly="-18" urx="566" ury="562"/>
<char name="K" width="600" llx="38" lly="0" urx="582" ury="562"/>
<char name="L" width="600" llx="47" lly="0" urx="554" ury="562"/>
<char name="Lslash" width="600" llx="47" lly="0" urx="554" ury="562"/>
<char name="M" width="600" llx="4" lly="0" urx="596" ury="562"/>
<char name="N" width="600" llx="7" lly="-13" urx="593" ury="562"/>
<char name="Ntilde" width="600" llx="7" lly="-13" urx="593" ury="729"/>
<char name="O" width="600" llx="43" lly="-18" urx="557" ury="580"/>
<char name="OE" width="600" llx="7" lly="0" urx="567" ury="562"/>
<char name="Oacute" width="600" llx="43" lly="-18" urx="557" ury="805"/>
<char name="Ocircumflex" width="600" llx="43" lly="-18" urx="557" ury="787"/>
<char name="Odieresis" width="600" llx="43" lly="-18" urx="557" ury="753"/>
<char name="Ograve" width="600" llx="43" lly="-18" urx="557" ury="805"/>
<char name="Oslash" width="600" llx="43" lly="-80" urx="557" ury="629"/>
<char name="Otilde" width="600" llx="43" lly="-18" urx="557" ury="729"/>
<char name="P" width="600" llx="79" lly="0" urx="558" ury="562"/>
<char name="Q" width="600" llx="43" lly="-138" urx="557" ury="580"/>
<char name="R" width="600" llx="38" lly="0" urx="588" ury="562"/>
<char name="S" width="600" llx="72" lly="-20" urx="529" ury="580"/>
<char name="Scaron" width="600" llx="72" lly="-20" urx="529" ury="802"/>
<char name="Scedilla" width="600" llx="72" lly="-151" urx="529" ury="580"/>
<char name="T" width="600" llx="38" lly="0" urx="563" ury="562"/>
<char name="Thorn" width="600" llx="79" lly="0" urx="538" ury="562"/>
<char name="U" width="600" llx="17" lly="-18" urx="583" ury="562"/>
<char name="Uacute" width="600" llx="17" lly="-18" urx="583" ury="805"/>
<char name="Ucircumflex" width="600" llx="17" lly="-18" urx="583" ury="787"/>
<char name="Udieresis" width="600" llx="17" lly="-18" urx="583" ury="753"/>
<char name="Ugrave" width="600" llx="17" lly="-18" urx="583" ury="805"/>
<char name="V" width="600" llx="-4" lly="-13" urx="604" ury="562"/>
<char name="W" width="600" llx="-3" lly="-13" urx="603" ury="562"/>
<char name="X" width="600" llx="23" lly="0" urx="577" ury="562"/>
<char name="Y" width="600" llx="24" lly="0" urx="576" ury="562"/>
<char name="Yacute" width="600" llx="24" lly="0" urx="576" ury="805"/>
<char name="Ydieresis" width="600" llx="24" lly="0" urx="576" ury="753"/>
<char name="Z" width="600" llx="86" lly="0" urx="514" ury="562"/>
<char name="Zcaron" width="600" llx="86" lly="0" urx="514" ury="802"/>
<char name="a" width="600" llx="53" lly="-15" urx="559" ury="441"/>
<char name="aacute" width="600" llx="53" lly="-15" urx="559" ury="672"/>
<char name="acircumflex" width="600" llx="53" lly="-15" urx="559" ury="654"/>
<char name="acute" width="600" llx="242" lly="497" urx="469" ury="672"/>
<char name="adieresis" width="600" llx="53" lly="-15" urx="559" ury="620"/>
<char name="ae" width="600" llx="19" lly="-15" urx="570" ury="441"/>
<char name="agrave" width="600" llx="53" lly="-15" urx="559" ury="672"/>
<char name="ampersand" width="600" llx="63" lly="-15" urx="538" ury="543"/>
<char name="aring" width="600" llx="53" lly="-15" urx="559" ury="627"/>
<char name="asciicircum" width="600" llx="94" lly="354" urx="506" ury="622"/>
<char name="asciitilde" width="600" llx="63" lly="197" urx="540" ury="320"/>
<char name="asterisk" width="600" llx="116" lly="257" urx="484" ury="607"/>
<char name="at" width="600" llx="77" lly="-15" urx="533" ury="622"/>
<char name="atilde" width="600" llx="53" lly="-15" urx="559" ury="606"/>
<char name="b" width="600" llx="14" lly="-15" urx="575" ury="629"/>
<char name="backslash" width="600" llx="118" lly="-80" urx="482" ury="629"/>
<char name="bar" width="600" llx="275" lly="-250" urx="326" ury="750"/>
<char name="braceleft" width="600" llx="182" lly="-108" urx="437" ury="622"/>
<char name="braceright" width="600" llx="163" lly="-108" urx="418" ury="622"/>
<char name="bracketleft" width="600" llx="269" lly="-108" urx="442" ury="622"/>
<char name="bracketright" width="600" llx="158" lly="-108" urx="331" ury="622"/>
<char name="breve" width="600" llx="153" lly="501" urx="447" ury="609"/>
<char name="brokenbar" width="600" llx="275" lly="-175" urx="326" ury="675"/>
<char name="bullet" width="600" llx="172" lly="130" urx="428" ury="383"/>
<char name="c" width="600" llx="66" lly="-15" urx="529" ury="441"/>
<char name="caron" width="600" llx="124" lly="492" urx="476" ury="669"/>
<char name="ccedilla" width="600" llx="66" lly="-151" urx="529" ury="441"/>
<char name="cedilla" width="600" llx="224" lly="-151" urx="362" ury="10"/>
<char name="cent" width="600" llx="96" lly="-49" urx="500" ury="614"/>
<char name="circumflex" width="600" llx="124" lly="477" urx="476" ury="654"/>
<char name="colon" width="600" llx="229" lly="-15" urx="371" ury="385"/>
<char name="comma" width="600" llx="181" lly="-112" urx="344" ury="122"/>
<char name="copyright" width="600" llx="0" lly="-18" urx="600" ury="580"/>
<char name="currency" width="600" llx="73" lly="58" urx="527" ury="506"/>
<char name="d" width="600" llx="45" lly="-15" urx="591" ury="629"/>
<char name="dagger" width="600" llx="141" lly="-78" urx="459" ury="580"/>
<char name="daggerdbl" width="600" llx="141" lly="-78" urx="459" ury="580"/>
<char name="degree" width="600" llx="123" lly="269" urx="477" ury="622"/>
<char name="dieresis" width="600" llx="148" lly="537" urx="453" ury="640"/>
<char name="divide" width="600" llx="87" lly="48" urx="513" ury="467"/>
<char name="dollar" width="600" llx="105" lly="-126" urx="496" ury="662"/>
<char name="dotaccent" width="600" llx="249" lly="537" urx="352" ury="640"/>
<char name="dotlessi" width="600" llx="95" lly="0" urx="505" ury="426"/>
<char name="e" width="600" llx="66" lly="-15" urx="548" ury="441"/>
<char name="eacute" width="600" llx="66" lly="-15" urx="548" ury="672"/>
<char name="ecircumflex" width="600" llx="66" lly="-15" urx="548" ury="654"/>
<char name="edieresis" width="600" llx="66" lly="-15" urx="548" ury="620"/>
<char name="egrave" width="600" llx="66" lly="-15" urx="548" ury="672"/>
<char name="eight" width="600" llx="102" lly="-15" urx="498" ury="622"/>
<char name="ellipsis" width="600" llx="37" lly="-15" urx="563" ury="111"/>
<char name="emdash" width="600" llx="0" lly="231" urx="600" ury="285"/>
<char name="endash" width="600" llx="75" lly="231" urx="525" ury="285"/>
<char name="equal" width="600" llx="80" lly="138" urx="520" ury="376"/>
<char name="eth" width="600" llx="62" lly="-15" urx="538" ury="629"/>
<char name="exclam" width="600" llx="236" lly="-15" urx="364" ury="572"/>
<char name="exclamdown" width="600" llx="236" lly="-157" urx="364" ury="430"/>
<char name="f" width="600" llx="114" lly="0" urx="531" ury="629"/>
<char name="fi" width="600" llx="3" lly="0" urx="597" ury="629"/>
<char name="five" width="600" llx="92" lly="-15" urx="497" ury="607"/>
<char name="fl" width="600" llx="3" lly="0" urx="597" ury="629"/>
<char name="florin" width="600" llx="4" lly="-143" urx="539" ury="622"/>
<char name="four" width="600" llx="78" lly="0" urx="500" ury="622"/>
<char name="fraction" width="600" llx="92" lly="-57" urx="509" ury="665"/>
<char name="g" width="600" llx="45" lly="-157" urx="566" ury="441"/>
<char name="germandbls" width="600" llx="48" lly="-15" urx="588" ury="629"/>
<char name="grave" width="600" llx="151" lly="497" urx="378" ury="672"/>
<char name="greater" width="600" llx="66" lly="42" urx="544" ury="472"/>
<char name="guillemotleft" width="600" llx="37" lly="70" urx="563" ury="446"/>
<char name="guillemotright" width="600" llx="37" lly="70" urx="563" ury="446"/>
<char name="guilsinglleft" width="600" llx="149" lly="70" urx="451" ury="446"/>
<char name="guilsinglright" width="600" llx="149" lly="70" urx="451" ury="446"/>
<char name="h" width="600" llx="18" lly="0" urx="582" ury="629"/>
<char name="hungarumlaut" width="600" llx="133" lly="497" urx="540" ury="672"/>
<char name="hyphen" width="600" llx="103" lly="231" urx="497" ury="285"/>
<char name="i" width="600" llx="95" lly="0" urx="505" ury="657"/>
<char name="iacute" width="600" llx="95" lly="0" urx="505" ury="672"/>
<char name="icircumflex" width="600" llx="94" lly="0" urx="505" ury="654"/>
<char name="idieresis" width="600" llx="95" lly="0" urx="505" ury="620"/>
<char name="igrave" width="600" llx="95" lly="0" urx="505" ury="672"/>
<char name="j" width="600" llx="82" lly="-157" urx="410" ury="657"/>
<char name="k" width="600" llx="43" lly="0" urx="580" ury="629"/>
<char name="l" width="600" llx="95" lly="0" urx="505" ury="629"/>
<char name="less" width="600" llx="41" lly="42" urx="519" ury="472"/>
<char name="logicalnot" width="600" llx="87" lly="108" urx="513" ury="369"/>
<char name="lslash" width="600" llx="95" lly="0" urx="505" ury="629"/>
<char name="m" width="600" llx="-5" lly="0" urx="605" ury="441"/>
<char name="macron" width="600" llx="120" lly="525" urx="480" ury="565"/>
<char name="minus" width="600" llx="80" lly="232" urx="520" ury="283"/>
<char name="mu" width="600" llx="21" lly="-157" urx="562" ury="426"/>
<char name="multiply" width="600" llx="87" lly="43" urx="515" ury="470"/>
<char name="n" width="600" llx="26" lly="0" urx="575" ury="441"/>
<char name="nine" width="600" llx="96" lly="-15" urx="489" ury="622"/>
<char name="ntilde" width="600" llx="26" lly="0" urx="575" ury="606"/>
<char name="numbersign" width="600" llx="93" lly="-32" urx="507" ury="639"/>
<char name="o" width="600" llx="62" lly="-15" urx="538" ury="441"/>
<char name="oacute" width="600" llx="62" lly="-15" urx="538" ury="672"/>
<char name="ocircumflex" width="600" llx="62" lly="-15" urx="538" ury="654"/>
<char name="odieresis" width="600" llx="62" lly="-15" urx="538" ury="620"/>
<char name="oe" width="600" llx="19" lly="-15" urx="559" ury="441"/>
<char name="ogonek" width="600" llx="211" lly="-172" urx="407" ury="4"/>
<char name="ograve" width="600" llx="62" lly="-15" urx="538" ury="672"/>
<char name="one" width="600" llx="96" lly="0" urx="505" ury="622"/>
<char name="onehalf" width="600" llx="0" lly="-57" urx="611" ury="665"/>
<char name="onequarter" width="600" llx="0" lly="-57" urx="600" ury="665"/>
<char name="onesuperior" width="600" llx="172" lly="249" urx="428" ury="622"/>
<char name="ordfeminine" width="600" llx="156" lly="249" urx="442" ury="580"/>
<char name="ordmasculine" width="600" llx="157" lly="249" urx="443" ury="580"/>
<char name="oslash" width="600" llx="62" lly="-80" urx="538" ury="506"/>
<char name="otilde" width="600" llx="62" lly="-15" urx="538" ury="606"/>
<char name="p" width="600" llx="9" lly="-157" urx="555" ury="441"/>
<char name="paragraph" width="600" llx="50" lly="-78" urx="511" ury="562"/>
<char name="parenleft" width="600" llx="269" lly="-108" urx="440" ury="622"/>
<char name="parenright" width="600" llx="160" lly="-108" urx="331" ury="622"/>
<char name="percent" width="600" llx="81" lly="-15" urx="518" ury="622"/>
<char name="period" width="600" llx="229" lly="-15" urx="371" ury="109"/>
<char name="periodcentered" width="600" llx="222" lly="189" urx="378" ury="327"/>
<char name="perthousand" width="600" llx="3" lly="-15" urx="600" ury="622"/>
<char name="plus" width="600" llx="80" lly="44" urx="520" ury="470"/>
<char name="plusminus" width="600" llx="87" lly="44" urx="513" ury="558"/>
<char name="q" width="600" llx="45" lly="-157" urx="591" ury="441"/>
<char name="question" width="600" llx="129" lly="-15" urx="492" ury="572"/>
<char name="questiondown" width="600" llx="108" lly="-157" urx="471" ury="430"/>
<char name="quotedbl" width="600" llx="187" lly="328" urx="413" ury="562"/>
<char name="quotedblbase" width="600" llx="143" lly="-134" urx="457" ury="100"/>
<char name="quotedblleft" width="600" llx="143" lly="328" urx="471" ury="562"/>
<char name="quotedblright" width="600" llx="143" lly="328" urx="457" ury="562"/>
<char name="quoteleft" width="600" llx="224" lly="328" urx="387" ury="562"/>
<char name="quoteright" width="600" llx="213" lly="328" urx="376" ury="562"/>
<char name="quotesinglbase" width="600" llx="213" lly="-134" urx="376" ury="100"/>
<char name="quotesingle" width="600" llx="259" lly="328" urx="341" ury="562"/>
<char name="r" width="600" llx="60" lly="0" urx="559" ury="441"/>
<char name="registered" width="600" llx="0" lly="-18" urx="600" ury="580"/>
<char name="ring" width="600" llx="218" lly="463" urx="382" ury="627"/>
<char name="s" width="600" llx="80" lly="-15" urx="513" ury="441"/>
<char name="scaron" width="600" llx="80" lly="-15" urx="513" ury="669"/>
<char name="scedilla" width="600" llx="80" lly="-151" urx="513" ury="441"/>
<char name="section" width="600" llx="113" lly="-78" urx="488" ury="580"/>
<char name="semicolon" width="600" llx="181" lly="-112" urx="371" ury="385"/>
<char name="seven" width="600" llx="82" lly="0" urx="483" ury="607"/>
<char name="six" width="600" llx="111" lly="-15" urx="497" ury="622"/>
<char name="slash" width="600" llx="125" lly="-80" urx="475" ury="629"/>
<char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="600"/>
<char name="square" width="600"/>
<char name="sterling" width="600"/>
<char name="stop" width="600"/>
<char name="t" width="600"/>
<char name="tab" width="600"/>
<char name="thorn" width="600"/>
<char name="three" width="600"/>
<char name="threequarters" width="600"/>
<char name="threesuperior" width="600"/>
<char name="tilde" width="600"/>
<char name="trademark" width="600"/>
<char name="two" width="600"/>
<char name="twosuperior" width="600"/>
<char name="u" width="600"/>
<char name="uacute" width="600"/>
<char name="ucircumflex" width="600"/>
<char name="udieresis" width="600"/>
<char name="ugrave" width="600"/>
<char name="underscore" width="600"/>
<char name="up" width="600"/>
<char name="v" width="600"/>
<char name="w" width="600"/>
<char name="x" width="600"/>
<char name="y" width="600"/>
<char name="yacute" width="600"/>
<char name="ydieresis" width="600"/>
<char name="yen" width="600"/>
<char name="z" width="600"/>
<char name="zcaron" width="600"/>
<char name="zero" width="600"/>
</widths>
</font-metrics>
<char name="sterling" width="600" llx="84" lly="-21" urx="521" ury="611"/>
<char name="t" width="600" llx="87" lly="-15" urx="530" ury="561"/>
<char name="thorn" width="600" llx="-6" lly="-157" urx="555" ury="629"/>
<char name="three" width="600" llx="75" lly="-15" urx="466" ury="622"/>
<char name="threequarters" width="600" llx="8" lly="-56" urx="593" ury="666"/>
<char name="threesuperior" width="600" llx="155" lly="240" urx="406" ury="622"/>
<char name="tilde" width="600" llx="105" lly="489" urx="503" ury="606"/>
<char name="trademark" width="600" llx="-23" lly="263" urx="623" ury="562"/>
<char name="two" width="600" llx="70" lly="0" urx="471" ury="622"/>
<char name="twosuperior" width="600" llx="177" lly="249" urx="424" ury="622"/>
<char name="u" width="600" llx="21" lly="-15" urx="562" ury="426"/>
<char name="uacute" width="600" llx="21" lly="-15" urx="562" ury="672"/>
<char name="ucircumflex" width="600" llx="21" lly="-15" urx="562" ury="654"/>
<char name="udieresis" width="600" llx="21" lly="-15" urx="562" ury="620"/>
<char name="ugrave" width="600" llx="21" lly="-15" urx="562" ury="672"/>
<char name="underscore" width="600" llx="0" lly="-125" urx="600" ury="-75"/>
<char name="v" width="600" llx="10" lly="-10" urx="590" ury="426"/>
<char name="w" width="600" llx="-4" lly="-10" urx="604" ury="426"/>
<char name="x" width="600" llx="20" lly="0" urx="580" ury="426"/>
<char name="y" width="600" llx="7" lly="-157" urx="592" ury="426"/>
<char name="yacute" width="600" llx="7" lly="-157" urx="592" ury="672"/>
<char name="ydieresis" width="600" llx="7" lly="-157" urx="592" ury="620"/>
<char name="yen" width="600" llx="26" lly="0" urx="574" ury="562"/>
<char name="z" width="600" llx="99" lly="0" urx="502" ury="426"/>
<char name="zcaron" width="600" llx="99" lly="0" urx="502" ury="669"/>
<char name="zero" width="600" llx="106" lly="-15" urx="494" ury="622"/>
</char-metrics>
</font-metrics>

+ 236
- 265
src/codegen/fonts/CourierBold.xml View File

@@ -22,275 +22,246 @@
<family-name>Courier</family-name>
<class-name>CourierBold</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>562</cap-height>
<x-height>439</x-height>
<ascender>626</ascender>
<descender>-142</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="600"/>
<char name="AE" width="600"/>
<char name="Aacute" width="600"/>
<char name="Acircumflex" width="600"/>
<char name="Adieresis" width="600"/>
<char name="Agrave" width="600"/>
<char name="Aring" width="600"/>
<char name="Atilde" width="600"/>
<char name="B" width="600"/>
<char name="C" width="600"/>
<char name="Ccedilla" width="600"/>
<char name="D" width="600"/>
<char name="E" width="600"/>
<char name="Eacute" width="600"/>
<char name="Ecircumflex" width="600"/>
<char name="Edieresis" width="600"/>
<char name="Egrave" width="600"/>
<char name="Eth" width="600"/>
<char name="Euro" width="600"/>
<char name="F" width="600"/>
<char name="G" width="600"/>
<char name="Gcaron" width="600"/>
<char name="H" width="600"/>
<char name="I" width="600"/>
<char name="IJ" width="600"/>
<char name="Iacute" width="600"/>
<char name="Icircumflex" width="600"/>
<char name="Idieresis" width="600"/>
<char name="Idot" width="600"/>
<char name="Igrave" width="600"/>
<char name="J" width="600"/>
<char name="K" width="600"/>
<char name="L" width="600"/>
<char name="LL" width="600"/>
<char name="Lslash" width="600"/>
<char name="M" width="600"/>
<char name="N" width="600"/>
<char name="Ntilde" width="600"/>
<char name="O" width="600"/>
<char name="OE" width="600"/>
<char name="Oacute" width="600"/>
<char name="Ocircumflex" width="600"/>
<char name="Odieresis" width="600"/>
<char name="Ograve" width="600"/>
<char name="Oslash" width="600"/>
<char name="Otilde" width="600"/>
<char name="P" width="600"/>
<char name="Q" width="600"/>
<char name="R" width="600"/>
<char name="S" width="600"/>
<char name="Scaron" width="600"/>
<char name="Scedilla" width="600"/>
<char name="T" width="600"/>
<char name="Thorn" width="600"/>
<char name="U" width="600"/>
<char name="Uacute" width="600"/>
<char name="Ucircumflex" width="600"/>
<char name="Udieresis" width="600"/>
<char name="Ugrave" width="600"/>
<char name="V" width="600"/>
<char name="W" width="600"/>
<char name="X" width="600"/>
<char name="Y" width="600"/>
<char name="Yacute" width="600"/>
<char name="Ydieresis" width="600"/>
<char name="Z" width="600"/>
<char name="Zcaron" width="600"/>
<char name="a" width="600"/>
<char name="aacute" width="600"/>
<char name="acircumflex" width="600"/>
<char name="acute" width="600"/>
<char name="adieresis" width="600"/>
<char name="ae" width="600"/>
<char name="agrave" width="600"/>
<char name="ampersand" width="600"/>
<char name="aring" width="600"/>
<char name="arrowboth" width="600"/>
<char name="arrowdown" width="600"/>
<char name="arrowleft" width="600"/>
<char name="arrowright" width="600"/>
<char name="arrowup" width="600"/>
<char name="asciicircum" width="600"/>
<char name="asciitilde" width="600"/>
<char name="asterisk" width="600"/>
<char name="at" width="600"/>
<char name="atilde" width="600"/>
<char name="b" width="600"/>
<char name="backslash" width="600"/>
<char name="bar" width="600"/>
<char name="braceleft" width="600"/>
<char name="braceright" width="600"/>
<char name="bracketleft" width="600"/>
<char name="bracketright" width="600"/>
<char name="breve" width="600"/>
<char name="brokenbar" width="600"/>
<char name="bullet" width="600"/>
<char name="c" width="600"/>
<char name="caron" width="600"/>
<char name="ccedilla" width="600"/>
<char name="cedilla" width="600"/>
<char name="cent" width="600"/>
<char name="center" width="600"/>
<char name="circumflex" width="600"/>
<char name="colon" width="600"/>
<char name="comma" width="600"/>
<char name="copyright" width="600"/>
<char name="currency" width="600"/>
<char name="d" width="600"/>
<char name="dagger" width="600"/>
<char name="daggerdbl" width="600"/>
<char name="dectab" width="600"/>
<char name="degree" width="600"/>
<char name="dieresis" width="600"/>
<char name="divide" width="600"/>
<char name="dollar" width="600"/>
<char name="dotaccent" width="600"/>
<char name="dotlessi" width="600"/>
<char name="down" width="600"/>
<char name="e" width="600"/>
<char name="eacute" width="600"/>
<char name="ecircumflex" width="600"/>
<char name="edieresis" width="600"/>
<char name="egrave" width="600"/>
<char name="eight" width="600"/>
<char name="ellipsis" width="600"/>
<char name="emdash" width="600"/>
<char name="endash" width="600"/>
<char name="equal" width="600"/>
<char name="eth" width="600"/>
<char name="exclam" width="600"/>
<char name="exclamdown" width="600"/>
<char name="f" width="600"/>
<char name="fi" width="600"/>
<char name="five" width="600"/>
<char name="fl" width="600"/>
<char name="florin" width="600"/>
<char name="format" width="600"/>
<char name="four" width="600"/>
<char name="fraction" width="600"/>
<char name="g" width="600"/>
<char name="gcaron" width="600"/>
<char name="germandbls" width="600"/>
<char name="grave" width="600"/>
<char name="graybox" width="600"/>
<char name="greater" width="600"/>
<char name="guillemotleft" width="600"/>
<char name="guillemotright" width="600"/>
<char name="guilsinglleft" width="600"/>
<char name="guilsinglright" width="600"/>
<char name="h" width="600"/>
<char name="hungarumlaut" width="600"/>
<char name="hyphen" width="600"/>
<char name="i" width="600"/>
<char name="iacute" width="600"/>
<char name="icircumflex" width="600"/>
<char name="idieresis" width="600"/>
<char name="igrave" width="600"/>
<char name="ij" width="600"/>
<char name="indent" width="600"/>
<char name="j" width="600"/>
<char name="k" width="600"/>
<char name="l" width="600"/>
<char name="largebullet" width="600"/>
<char name="left" width="600"/>
<char name="less" width="600"/>
<char name="lira" width="600"/>
<char name="ll" width="600"/>
<char name="logicalnot" width="600"/>
<char name="lslash" width="600"/>
<char name="m" width="600"/>
<char name="macron" width="600"/>
<char name="merge" width="600"/>
<char name="minus" width="600"/>
<char name="mu" width="600"/>
<char name="multiply" width="600"/>
<char name="n" width="600"/>
<char name="nine" width="600"/>
<char name="notegraphic" width="600"/>
<char name="ntilde" width="600"/>
<char name="numbersign" width="600"/>
<char name="o" width="600"/>
<char name="oacute" width="600"/>
<char name="ocircumflex" width="600"/>
<char name="odieresis" width="600"/>
<char name="oe" width="600"/>
<char name="ogonek" width="600"/>
<char name="ograve" width="600"/>
<char name="one" width="600"/>
<char name="onehalf" width="600"/>
<char name="onequarter" width="600"/>
<char name="onesuperior" width="600"/>
<char name="ordfeminine" width="600"/>
<char name="ordmasculine" width="600"/>
<char name="oslash" width="600"/>
<char name="otilde" width="600"/>
<char name="overscore" width="600"/>
<char name="p" width="600"/>
<char name="paragraph" width="600"/>
<char name="parenleft" width="600"/>
<char name="parenright" width="600"/>
<char name="percent" width="600"/>
<char name="period" width="600"/>
<char name="periodcentered" width="600"/>
<char name="perthousand" width="600"/>
<char name="plus" width="600"/>
<char name="plusminus" width="600"/>
<char name="prescription" width="600"/>
<char name="q" width="600"/>
<char name="question" width="600"/>
<char name="questiondown" width="600"/>
<char name="quotedbl" width="600"/>
<char name="quotedblbase" width="600"/>
<char name="quotedblleft" width="600"/>
<char name="quotedblright" width="600"/>
<char name="quoteleft" width="600"/>
<char name="quoteright" width="600"/>
<char name="quotesinglbase" width="600"/>
<char name="quotesingle" width="600"/>
<char name="r" width="600"/>
<char name="registered" width="600"/>
<char name="return" width="600"/>
<char name="ring" width="600"/>
<char name="s" width="600"/>
<char name="scaron" width="600"/>
<char name="scedilla" width="600"/>
<char name="section" width="600"/>
<char name="semicolon" width="600"/>
<char name="seven" width="600"/>
<char name="six" width="600"/>
<char name="slash" width="600"/>
<char name="space" width="600"/>
<char-metrics>
<char name="A" width="600" llx="-9" lly="0" urx="609" ury="562"/>
<char name="AE" width="600" llx="-29" lly="0" urx="602" ury="562"/>
<char name="Aacute" width="600" llx="-9" lly="0" urx="609" ury="784"/>
<char name="Acircumflex" width="600" llx="-9" lly="0" urx="609" ury="780"/>
<char name="Adieresis" width="600" llx="-9" lly="0" urx="609" ury="761"/>
<char name="Agrave" width="600" llx="-9" lly="0" urx="609" ury="784"/>
<char name="Aring" width="600" llx="-9" lly="0" urx="609" ury="801"/>
<char name="Atilde" width="600" llx="-9" lly="0" urx="609" ury="759"/>
<char name="B" width="600" llx="30" lly="0" urx="573" ury="562"/>
<char name="C" width="600" llx="22" lly="-18" urx="560" ury="580"/>
<char name="Ccedilla" width="600" llx="22" lly="-206" urx="560" ury="580"/>
<char name="D" width="600" llx="30" lly="0" urx="594" ury="562"/>
<char name="E" width="600" llx="25" lly="0" urx="560" ury="562"/>
<char name="Eacute" width="600" llx="25" lly="0" urx="560" ury="784"/>
<char name="Ecircumflex" width="600" llx="25" lly="0" urx="560" ury="780"/>
<char name="Edieresis" width="600" llx="25" lly="0" urx="560" ury="761"/>
<char name="Egrave" width="600" llx="25" lly="0" urx="560" ury="784"/>
<char name="Eth" width="600" llx="30" lly="0" urx="594" ury="562"/>
<char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="600" llx="39" lly="0" urx="570" ury="562"/>
<char name="G" width="600" llx="22" lly="-18" urx="594" ury="580"/>
<char name="H" width="600" llx="20" lly="0" urx="580" ury="562"/>
<char name="I" width="600" llx="77" lly="0" urx="523" ury="562"/>
<char name="Iacute" width="600" llx="77" lly="0" urx="523" ury="784"/>
<char name="Icircumflex" width="600" llx="77" lly="0" urx="523" ury="780"/>
<char name="Idieresis" width="600" llx="77" lly="0" urx="523" ury="761"/>
<char name="Igrave" width="600" llx="77" lly="0" urx="523" ury="784"/>
<char name="J" width="600" llx="37" lly="-18" urx="601" ury="562"/>
<char name="K" width="600" llx="21" lly="0" urx="599" ury="562"/>
<char name="L" width="600" llx="39" lly="0" urx="578" ury="562"/>
<char name="Lslash" width="600" llx="39" lly="0" urx="578" ury="562"/>
<char name="M" width="600" llx="-2" lly="0" urx="602" ury="562"/>
<char name="N" width="600" llx="8" lly="-12" urx="610" ury="562"/>
<char name="Ntilde" width="600" llx="8" lly="-12" urx="610" ury="759"/>
<char name="O" width="600" llx="22" lly="-18" urx="578" ury="580"/>
<char name="OE" width="600" llx="-25" lly="0" urx="595" ury="562"/>
<char name="Oacute" width="600" llx="22" lly="-18" urx="578" ury="784"/>
<char name="Ocircumflex" width="600" llx="22" lly="-18" urx="578" ury="780"/>
<char name="Odieresis" width="600" llx="22" lly="-18" urx="578" ury="761"/>
<char name="Ograve" width="600" llx="22" lly="-18" urx="578" ury="784"/>
<char name="Oslash" width="600" llx="22" lly="-22" urx="578" ury="584"/>
<char name="Otilde" width="600" llx="22" lly="-18" urx="578" ury="759"/>
<char name="P" width="600" llx="48" lly="0" urx="559" ury="562"/>
<char name="Q" width="600" llx="32" lly="-138" urx="578" ury="580"/>
<char name="R" width="600" llx="24" lly="0" urx="599" ury="562"/>
<char name="S" width="600" llx="47" lly="-22" urx="553" ury="582"/>
<char name="Scaron" width="600" llx="47" lly="-22" urx="553" ury="790"/>
<char name="Scedilla" width="600" llx="47" lly="-206" urx="553" ury="582"/>
<char name="T" width="600" llx="21" lly="0" urx="579" ury="562"/>
<char name="Thorn" width="600" llx="48" lly="0" urx="557" ury="562"/>
<char name="U" width="600" llx="4" lly="-18" urx="596" ury="562"/>
<char name="Uacute" width="600" llx="4" lly="-18" urx="596" ury="784"/>
<char name="Ucircumflex" width="600" llx="4" lly="-18" urx="596" ury="780"/>
<char name="Udieresis" width="600" llx="4" lly="-18" urx="596" ury="761"/>
<char name="Ugrave" width="600" llx="4" lly="-18" urx="596" ury="784"/>
<char name="V" width="600" llx="-13" lly="0" urx="613" ury="562"/>
<char name="W" width="600" llx="-18" lly="0" urx="618" ury="562"/>
<char name="X" width="600" llx="12" lly="0" urx="588" ury="562"/>
<char name="Y" width="600" llx="12" lly="0" urx="589" ury="562"/>
<char name="Yacute" width="600" llx="12" lly="0" urx="589" ury="784"/>
<char name="Ydieresis" width="600" llx="12" lly="0" urx="589" ury="761"/>
<char name="Z" width="600" llx="62" lly="0" urx="539" ury="562"/>
<char name="Zcaron" width="600" llx="62" lly="0" urx="539" ury="790"/>
<char name="a" width="600" llx="35" lly="-15" urx="570" ury="454"/>
<char name="aacute" width="600" llx="35" lly="-15" urx="570" ury="661"/>
<char name="acircumflex" width="600" llx="35" lly="-15" urx="570" ury="657"/>
<char name="acute" width="600" llx="205" lly="508" urx="468" ury="661"/>
<char name="adieresis" width="600" llx="35" lly="-15" urx="570" ury="638"/>
<char name="ae" width="600" llx="-4" lly="-15" urx="601" ury="454"/>
<char name="agrave" width="600" llx="35" lly="-15" urx="570" ury="661"/>
<char name="ampersand" width="600" llx="36" lly="-15" urx="546" ury="543"/>
<char name="aring" width="600" llx="35" lly="-15" urx="570" ury="678"/>
<char name="asciicircum" width="600" llx="108" lly="250" urx="492" ury="616"/>
<char name="asciitilde" width="600" llx="71" lly="153" urx="530" ury="356"/>
<char name="asterisk" width="600" llx="91" lly="219" urx="509" ury="601"/>
<char name="at" width="600" llx="16" lly="-15" urx="584" ury="616"/>
<char name="atilde" width="600" llx="35" lly="-15" urx="570" ury="636"/>
<char name="b" width="600" llx="0" lly="-15" urx="584" ury="626"/>
<char name="backslash" width="600" llx="99" lly="-77" urx="503" ury="626"/>
<char name="bar" width="600" llx="255" lly="-250" urx="345" ury="750"/>
<char name="braceleft" width="600" llx="160" lly="-102" urx="464" ury="616"/>
<char name="braceright" width="600" llx="136" lly="-102" urx="440" ury="616"/>
<char name="bracketleft" width="600" llx="245" lly="-102" urx="475" ury="616"/>
<char name="bracketright" width="600" llx="125" lly="-102" urx="355" ury="616"/>
<char name="breve" width="600" llx="83" lly="468" urx="517" ury="631"/>
<char name="brokenbar" width="600" llx="255" lly="-175" urx="345" ury="675"/>
<char name="bullet" width="600" llx="140" lly="132" urx="460" ury="430"/>
<char name="c" width="600" llx="40" lly="-15" urx="545" ury="459"/>
<char name="caron" width="600" llx="103" lly="493" urx="497" ury="667"/>
<char name="ccedilla" width="600" llx="40" lly="-206" urx="545" ury="459"/>
<char name="cedilla" width="600" llx="205" lly="-206" urx="387" ury="0"/>
<char name="cent" width="600" llx="66" lly="-49" urx="518" ury="614"/>
<char name="circumflex" width="600" llx="103" lly="483" urx="497" ury="657"/>
<char name="colon" width="600" llx="191" lly="-15" urx="407" ury="425"/>
<char name="comma" width="600" llx="123" lly="-111" urx="393" ury="174"/>
<char name="copyright" width="600" llx="0" lly="-18" urx="600" ury="580"/>
<char name="currency" width="600" llx="54" lly="49" urx="546" ury="517"/>
<char name="d" width="600" llx="20" lly="-15" urx="591" ury="626"/>
<char name="dagger" width="600" llx="106" lly="-70" urx="494" ury="580"/>
<char name="daggerdbl" width="600" llx="106" lly="-70" urx="494" ury="580"/>
<char name="degree" width="600" llx="86" lly="243" urx="474" ury="616"/>
<char name="dieresis" width="600" llx="128" lly="498" urx="472" ury="638"/>
<char name="divide" width="600" llx="71" lly="16" urx="529" ury="500"/>
<char name="dollar" width="600" llx="82" lly="-126" urx="519" ury="666"/>
<char name="dotaccent" width="600" llx="230" lly="498" urx="370" ury="638"/>
<char name="dotlessi" width="600" llx="77" lly="0" urx="523" ury="439"/>
<char name="e" width="600" llx="40" lly="-15" urx="563" ury="454"/>
<char name="eacute" width="600" llx="40" lly="-15" urx="563" ury="661"/>
<char name="ecircumflex" width="600" llx="40" lly="-15" urx="563" ury="657"/>
<char name="edieresis" width="600" llx="40" lly="-15" urx="563" ury="638"/>
<char name="egrave" width="600" llx="40" lly="-15" urx="563" ury="661"/>
<char name="eight" width="600" llx="83" lly="-15" urx="517" ury="616"/>
<char name="ellipsis" width="600" llx="26" lly="-15" urx="574" ury="116"/>
<char name="emdash" width="600" llx="-10" lly="203" urx="610" ury="313"/>
<char name="endash" width="600" llx="65" lly="203" urx="535" ury="313"/>
<char name="equal" width="600" llx="71" lly="118" urx="529" ury="398"/>
<char name="eth" width="600" llx="58" lly="-27" urx="543" ury="626"/>
<char name="exclam" width="600" llx="202" lly="-15" urx="398" ury="572"/>
<char name="exclamdown" width="600" llx="202" lly="-146" urx="398" ury="449"/>
<char name="f" width="600" llx="83" lly="0" urx="547" ury="626"/>
<char name="fi" width="600" llx="12" lly="0" urx="593" ury="626"/>
<char name="five" width="600" llx="70" lly="-15" urx="521" ury="601"/>
<char name="fl" width="600" llx="12" lly="0" urx="593" ury="626"/>
<char name="florin" width="600" llx="-30" lly="-131" urx="572" ury="616"/>
<char name="four" width="600" llx="53" lly="0" urx="507" ury="616"/>
<char name="fraction" width="600" llx="25" lly="-60" urx="576" ury="661"/>
<char name="g" width="600" llx="30" lly="-146" urx="580" ury="454"/>
<char name="germandbls" width="600" llx="22" lly="-15" urx="596" ury="626"/>
<char name="grave" width="600" llx="132" lly="508" urx="395" ury="661"/>
<char name="greater" width="600" llx="77" lly="15" urx="534" ury="501"/>
<char name="guillemotleft" width="600" llx="8" lly="70" urx="553" ury="446"/>
<char name="guillemotright" width="600" llx="47" lly="70" urx="592" ury="446"/>
<char name="guilsinglleft" width="600" llx="141" lly="70" urx="459" ury="446"/>
<char name="guilsinglright" width="600" llx="141" lly="70" urx="459" ury="446"/>
<char name="h" width="600" llx="5" lly="0" urx="592" ury="626"/>
<char name="hungarumlaut" width="600" llx="68" lly="488" urx="588" ury="661"/>
<char name="hyphen" width="600" llx="100" lly="203" urx="500" ury="313"/>
<char name="i" width="600" llx="77" lly="0" urx="523" ury="658"/>
<char name="iacute" width="600" llx="77" lly="0" urx="523" ury="661"/>
<char name="icircumflex" width="600" llx="73" lly="0" urx="523" ury="657"/>
<char name="idieresis" width="600" llx="77" lly="0" urx="523" ury="618"/>
<char name="igrave" width="600" llx="77" lly="0" urx="523" ury="661"/>
<char name="j" width="600" llx="63" lly="-146" urx="440" ury="658"/>
<char name="k" width="600" llx="20" lly="0" urx="585" ury="626"/>
<char name="l" width="600" llx="77" lly="0" urx="523" ury="626"/>
<char name="less" width="600" llx="66" lly="15" urx="523" ury="501"/>
<char name="logicalnot" width="600" llx="71" lly="103" urx="529" ury="413"/>
<char name="lslash" width="600" llx="77" lly="0" urx="523" ury="626"/>
<char name="m" width="600" llx="-22" lly="0" urx="626" ury="454"/>
<char name="macron" width="600" llx="88" lly="505" urx="512" ury="585"/>
<char name="minus" width="600" llx="71" lly="203" urx="529" ury="313"/>
<char name="mu" width="600" llx="-1" lly="-142" urx="569" ury="439"/>
<char name="multiply" width="600" llx="81" lly="39" urx="520" ury="478"/>
<char name="n" width="600" llx="18" lly="0" urx="592" ury="454"/>
<char name="nine" width="600" llx="79" lly="-15" urx="510" ury="616"/>
<char name="ntilde" width="600" llx="18" lly="0" urx="592" ury="636"/>
<char name="numbersign" width="600" llx="56" lly="-45" urx="544" ury="651"/>
<char name="o" width="600" llx="30" lly="-15" urx="570" ury="454"/>
<char name="oacute" width="600" llx="30" lly="-15" urx="570" ury="661"/>
<char name="ocircumflex" width="600" llx="30" lly="-15" urx="570" ury="657"/>
<char name="odieresis" width="600" llx="30" lly="-15" urx="570" ury="638"/>
<char name="oe" width="600" llx="-18" lly="-15" urx="611" ury="454"/>
<char name="ogonek" width="600" llx="169" lly="-199" urx="400" ury="0"/>
<char name="ograve" width="600" llx="30" lly="-15" urx="570" ury="661"/>
<char name="one" width="600" llx="81" lly="0" urx="539" ury="616"/>
<char name="onehalf" width="600" llx="-47" lly="-60" urx="648" ury="661"/>
<char name="onequarter" width="600" llx="-56" lly="-60" urx="656" ury="661"/>
<char name="onesuperior" width="600" llx="153" lly="230" urx="447" ury="616"/>
<char name="ordfeminine" width="600" llx="147" lly="196" urx="453" ury="580"/>
<char name="ordmasculine" width="600" llx="147" lly="196" urx="453" ury="580"/>
<char name="oslash" width="600" llx="30" lly="-24" urx="570" ury="463"/>
<char name="otilde" width="600" llx="30" lly="-15" urx="570" ury="636"/>
<char name="p" width="600" llx="-1" lly="-142" urx="570" ury="454"/>
<char name="paragraph" width="600" llx="6" lly="-70" urx="576" ury="580"/>
<char name="parenleft" width="600" llx="219" lly="-102" urx="461" ury="616"/>
<char name="parenright" width="600" llx="139" lly="-102" urx="381" ury="616"/>
<char name="percent" width="600" llx="5" lly="-15" urx="595" ury="616"/>
<char name="period" width="600" llx="192" lly="-15" urx="408" ury="171"/>
<char name="periodcentered" width="600" llx="196" lly="165" urx="404" ury="351"/>
<char name="perthousand" width="600" llx="-113" lly="-15" urx="713" ury="616"/>
<char name="plus" width="600" llx="71" lly="39" urx="529" ury="478"/>
<char name="plusminus" width="600" llx="71" lly="24" urx="529" ury="515"/>
<char name="q" width="600" llx="20" lly="-142" urx="591" ury="454"/>
<char name="question" width="600" llx="98" lly="-14" urx="501" ury="580"/>
<char name="questiondown" width="600" llx="99" lly="-146" urx="502" ury="449"/>
<char name="quotedbl" width="600" llx="135" lly="277" urx="465" ury="562"/>
<char name="quotedblbase" width="600" llx="65" lly="-142" urx="529" ury="143"/>
<char name="quotedblleft" width="600" llx="71" lly="277" urx="535" ury="562"/>
<char name="quotedblright" width="600" llx="61" lly="277" urx="525" ury="562"/>
<char name="quoteleft" width="600" llx="178" lly="277" urx="428" ury="562"/>
<char name="quoteright" width="600" llx="171" lly="277" urx="423" ury="562"/>
<char name="quotesinglbase" width="600" llx="175" lly="-142" urx="427" ury="143"/>
<char name="quotesingle" width="600" llx="227" lly="277" urx="373" ury="562"/>
<char name="r" width="600" llx="47" lly="0" urx="580" ury="454"/>
<char name="registered" width="600" llx="0" lly="-18" urx="600" ury="580"/>
<char name="ring" width="600" llx="198" lly="481" urx="402" ury="678"/>
<char name="s" width="600" llx="68" lly="-17" urx="535" ury="459"/>
<char name="scaron" width="600" llx="68" lly="-17" urx="535" ury="667"/>
<char name="scedilla" width="600" llx="68" lly="-206" urx="535" ury="459"/>
<char name="section" width="600" llx="83" lly="-70" urx="517" ury="580"/>
<char name="semicolon" width="600" llx="123" lly="-111" urx="408" ury="425"/>
<char name="seven" width="600" llx="55" lly="0" urx="494" ury="601"/>
<char name="six" width="600" llx="90" lly="-15" urx="521" ury="616"/>
<char name="slash" width="600" llx="98" lly="-77" urx="502" ury="626"/>
<char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="600"/>
<char name="square" width="600"/>
<char name="sterling" width="600"/>
<char name="stop" width="600"/>
<char name="t" width="600"/>
<char name="tab" width="600"/>
<char name="thorn" width="600"/>
<char name="three" width="600"/>
<char name="threequarters" width="600"/>
<char name="threesuperior" width="600"/>
<char name="tilde" width="600"/>
<char name="trademark" width="600"/>
<char name="two" width="600"/>
<char name="twosuperior" width="600"/>
<char name="u" width="600"/>
<char name="uacute" width="600"/>
<char name="ucircumflex" width="600"/>
<char name="udieresis" width="600"/>
<char name="ugrave" width="600"/>
<char name="underscore" width="600"/>
<char name="up" width="600"/>
<char name="v" width="600"/>
<char name="w" width="600"/>
<char name="x" width="600"/>
<char name="y" width="600"/>
<char name="yacute" width="600"/>
<char name="ydieresis" width="600"/>
<char name="yen" width="600"/>
<char name="z" width="600"/>
<char name="zcaron" width="600"/>
<char name="zero" width="600"/>
</widths>
</font-metrics>
<char name="sterling" width="600" llx="72" lly="-28" urx="558" ury="611"/>
<char name="t" width="600" llx="47" lly="-15" urx="532" ury="562"/>
<char name="thorn" width="600" llx="-14" lly="-142" urx="570" ury="626"/>
<char name="three" width="600" llx="63" lly="-15" urx="501" ury="616"/>
<char name="threequarters" width="600" llx="-47" lly="-60" urx="648" ury="661"/>
<char name="threesuperior" width="600" llx="138" lly="222" urx="433" ury="616"/>
<char name="tilde" width="600" llx="89" lly="493" urx="512" ury="636"/>
<char name="trademark" width="600" llx="-9" lly="230" urx="749" ury="562"/>
<char name="two" width="600" llx="61" lly="0" urx="499" ury="616"/>
<char name="twosuperior" width="600" llx="143" lly="230" urx="436" ury="616"/>
<char name="u" width="600" llx="-1" lly="-15" urx="569" ury="439"/>
<char name="uacute" width="600" llx="-1" lly="-15" urx="569" ury="661"/>
<char name="ucircumflex" width="600" llx="-1" lly="-15" urx="569" ury="657"/>
<char name="udieresis" width="600" llx="-1" lly="-15" urx="569" ury="638"/>
<char name="ugrave" width="600" llx="-1" lly="-15" urx="569" ury="661"/>
<char name="underscore" width="600" llx="0" lly="-125" urx="600" ury="-75"/>
<char name="v" width="600" llx="-1" lly="0" urx="601" ury="439"/>
<char name="w" width="600" llx="-18" lly="0" urx="618" ury="439"/>
<char name="x" width="600" llx="6" lly="0" urx="594" ury="439"/>
<char name="y" width="600" llx="-4" lly="-142" urx="601" ury="439"/>
<char name="yacute" width="600" llx="-4" lly="-142" urx="601" ury="661"/>
<char name="ydieresis" width="600" llx="-4" lly="-142" urx="601" ury="638"/>
<char name="yen" width="600" llx="10" lly="0" urx="590" ury="562"/>
<char name="z" width="600" llx="81" lly="0" urx="520" ury="439"/>
<char name="zcaron" width="600" llx="81" lly="0" urx="520" ury="667"/>
<char name="zero" width="600" llx="87" lly="-15" urx="513" ury="616"/>
</char-metrics>
</font-metrics>

+ 235
- 264
src/codegen/fonts/CourierBoldOblique.xml View File

@@ -22,275 +22,246 @@
<family-name>Courier</family-name>
<class-name>CourierBoldOblique</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>562</cap-height>
<x-height>439</x-height>
<ascender>626</ascender>
<descender>-142</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="600"/>
<char name="AE" width="600"/>
<char name="Aacute" width="600"/>
<char name="Acircumflex" width="600"/>
<char name="Adieresis" width="600"/>
<char name="Agrave" width="600"/>
<char name="Aring" width="600"/>
<char name="Atilde" width="600"/>
<char name="B" width="600"/>
<char name="C" width="600"/>
<char name="Ccedilla" width="600"/>
<char name="D" width="600"/>
<char name="E" width="600"/>
<char name="Eacute" width="600"/>
<char name="Ecircumflex" width="600"/>
<char name="Edieresis" width="600"/>
<char name="Egrave" width="600"/>
<char name="Eth" width="600"/>
<char name="Euro" width="600"/>
<char name="F" width="600"/>
<char name="G" width="600"/>
<char name="Gcaron" width="600"/>
<char name="H" width="600"/>
<char name="I" width="600"/>
<char name="IJ" width="600"/>
<char name="Iacute" width="600"/>
<char name="Icircumflex" width="600"/>
<char name="Idieresis" width="600"/>
<char name="Idot" width="600"/>
<char name="Igrave" width="600"/>
<char name="J" width="600"/>
<char name="K" width="600"/>
<char name="L" width="600"/>
<char name="LL" width="600"/>
<char name="Lslash" width="600"/>
<char name="M" width="600"/>
<char name="N" width="600"/>
<char name="Ntilde" width="600"/>
<char name="O" width="600"/>
<char name="OE" width="600"/>
<char name="Oacute" width="600"/>
<char name="Ocircumflex" width="600"/>
<char name="Odieresis" width="600"/>
<char name="Ograve" width="600"/>
<char name="Oslash" width="600"/>
<char name="Otilde" width="600"/>
<char name="P" width="600"/>
<char name="Q" width="600"/>
<char name="R" width="600"/>
<char name="S" width="600"/>
<char name="Scaron" width="600"/>
<char name="Scedilla" width="600"/>
<char name="T" width="600"/>
<char name="Thorn" width="600"/>
<char name="U" width="600"/>
<char name="Uacute" width="600"/>
<char name="Ucircumflex" width="600"/>
<char name="Udieresis" width="600"/>
<char name="Ugrave" width="600"/>
<char name="V" width="600"/>
<char name="W" width="600"/>
<char name="X" width="600"/>
<char name="Y" width="600"/>
<char name="Yacute" width="600"/>
<char name="Ydieresis" width="600"/>
<char name="Z" width="600"/>
<char name="Zcaron" width="600"/>
<char name="a" width="600"/>
<char name="aacute" width="600"/>
<char name="acircumflex" width="600"/>
<char name="acute" width="600"/>
<char name="adieresis" width="600"/>
<char name="ae" width="600"/>
<char name="agrave" width="600"/>
<char name="ampersand" width="600"/>
<char name="aring" width="600"/>
<char name="arrowboth" width="600"/>
<char name="arrowdown" width="600"/>
<char name="arrowleft" width="600"/>
<char name="arrowright" width="600"/>
<char name="arrowup" width="600"/>
<char name="asciicircum" width="600"/>
<char name="asciitilde" width="600"/>
<char name="asterisk" width="600"/>
<char name="at" width="600"/>
<char name="atilde" width="600"/>
<char name="b" width="600"/>
<char name="backslash" width="600"/>
<char name="bar" width="600"/>
<char name="braceleft" width="600"/>
<char name="braceright" width="600"/>
<char name="bracketleft" width="600"/>
<char name="bracketright" width="600"/>
<char name="breve" width="600"/>
<char name="brokenbar" width="600"/>
<char name="bullet" width="600"/>
<char name="c" width="600"/>
<char name="caron" width="600"/>
<char name="ccedilla" width="600"/>
<char name="cedilla" width="600"/>
<char name="cent" width="600"/>
<char name="center" width="600"/>
<char name="circumflex" width="600"/>
<char name="colon" width="600"/>
<char name="comma" width="600"/>
<char name="copyright" width="600"/>
<char name="currency" width="600"/>
<char name="d" width="600"/>
<char name="dagger" width="600"/>
<char name="daggerdbl" width="600"/>
<char name="dectab" width="600"/>
<char name="degree" width="600"/>
<char name="dieresis" width="600"/>
<char name="divide" width="600"/>
<char name="dollar" width="600"/>
<char name="dotaccent" width="600"/>
<char name="dotlessi" width="600"/>
<char name="down" width="600"/>
<char name="e" width="600"/>
<char name="eacute" width="600"/>
<char name="ecircumflex" width="600"/>
<char name="edieresis" width="600"/>
<char name="egrave" width="600"/>
<char name="eight" width="600"/>
<char name="ellipsis" width="600"/>
<char name="emdash" width="600"/>
<char name="endash" width="600"/>
<char name="equal" width="600"/>
<char name="eth" width="600"/>
<char name="exclam" width="600"/>
<char name="exclamdown" width="600"/>
<char name="f" width="600"/>
<char name="fi" width="600"/>
<char name="five" width="600"/>
<char name="fl" width="600"/>
<char name="florin" width="600"/>
<char name="format" width="600"/>
<char name="four" width="600"/>
<char name="fraction" width="600"/>
<char name="g" width="600"/>
<char name="gcaron" width="600"/>
<char name="germandbls" width="600"/>
<char name="grave" width="600"/>
<char name="graybox" width="600"/>
<char name="greater" width="600"/>
<char name="guillemotleft" width="600"/>
<char name="guillemotright" width="600"/>
<char name="guilsinglleft" width="600"/>
<char name="guilsinglright" width="600"/>
<char name="h" width="600"/>
<char name="hungarumlaut" width="600"/>
<char name="hyphen" width="600"/>
<char name="i" width="600"/>
<char name="iacute" width="600"/>
<char name="icircumflex" width="600"/>
<char name="idieresis" width="600"/>
<char name="igrave" width="600"/>
<char name="ij" width="600"/>
<char name="indent" width="600"/>
<char name="j" width="600"/>
<char name="k" width="600"/>
<char name="l" width="600"/>
<char name="largebullet" width="600"/>
<char name="left" width="600"/>
<char name="less" width="600"/>
<char name="lira" width="600"/>
<char name="ll" width="600"/>
<char name="logicalnot" width="600"/>
<char name="lslash" width="600"/>
<char name="m" width="600"/>
<char name="macron" width="600"/>
<char name="merge" width="600"/>
<char name="minus" width="600"/>
<char name="mu" width="600"/>
<char name="multiply" width="600"/>
<char name="n" width="600"/>
<char name="nine" width="600"/>
<char name="notegraphic" width="600"/>
<char name="ntilde" width="600"/>
<char name="numbersign" width="600"/>
<char name="o" width="600"/>
<char name="oacute" width="600"/>
<char name="ocircumflex" width="600"/>
<char name="odieresis" width="600"/>
<char name="oe" width="600"/>
<char name="ogonek" width="600"/>
<char name="ograve" width="600"/>
<char name="one" width="600"/>
<char name="onehalf" width="600"/>
<char name="onequarter" width="600"/>
<char name="onesuperior" width="600"/>
<char name="ordfeminine" width="600"/>
<char name="ordmasculine" width="600"/>
<char name="oslash" width="600"/>
<char name="otilde" width="600"/>
<char name="overscore" width="600"/>
<char name="p" width="600"/>
<char name="paragraph" width="600"/>
<char name="parenleft" width="600"/>
<char name="parenright" width="600"/>
<char name="percent" width="600"/>
<char name="period" width="600"/>
<char name="periodcentered" width="600"/>
<char name="perthousand" width="600"/>
<char name="plus" width="600"/>
<char name="plusminus" width="600"/>
<char name="prescription" width="600"/>
<char name="q" width="600"/>
<char name="question" width="600"/>
<char name="questiondown" width="600"/>
<char name="quotedbl" width="600"/>
<char name="quotedblbase" width="600"/>
<char name="quotedblleft" width="600"/>
<char name="quotedblright" width="600"/>
<char name="quoteleft" width="600"/>
<char name="quoteright" width="600"/>
<char name="quotesinglbase" width="600"/>
<char name="quotesingle" width="600"/>
<char name="r" width="600"/>
<char name="registered" width="600"/>
<char name="return" width="600"/>
<char name="ring" width="600"/>
<char name="s" width="600"/>
<char name="scaron" width="600"/>
<char name="scedilla" width="600"/>
<char name="section" width="600"/>
<char name="semicolon" width="600"/>
<char name="seven" width="600"/>
<char name="six" width="600"/>
<char name="slash" width="600"/>
<char name="space" width="600"/>
<char-metrics>
<char name="A" width="600" llx="-9" lly="0" urx="632" ury="562"/>
<char name="AE" width="600" llx="-29" lly="0" urx="708" ury="562"/>
<char name="Aacute" width="600" llx="-9" lly="0" urx="655" ury="784"/>
<char name="Acircumflex" width="600" llx="-9" lly="0" urx="632" ury="780"/>
<char name="Adieresis" width="600" llx="-9" lly="0" urx="632" ury="761"/>
<char name="Agrave" width="600" llx="-9" lly="0" urx="632" ury="784"/>
<char name="Aring" width="600" llx="-9" lly="0" urx="632" ury="801"/>
<char name="Atilde" width="600" llx="-9" lly="0" urx="669" ury="759"/>
<char name="B" width="600" llx="30" lly="0" urx="630" ury="562"/>
<char name="C" width="600" llx="74" lly="-18" urx="675" ury="580"/>
<char name="Ccedilla" width="600" llx="74" lly="-206" urx="675" ury="580"/>
<char name="D" width="600" llx="30" lly="0" urx="664" ury="562"/>
<char name="E" width="600" llx="25" lly="0" urx="670" ury="562"/>
<char name="Eacute" width="600" llx="25" lly="0" urx="670" ury="784"/>
<char name="Ecircumflex" width="600" llx="25" lly="0" urx="670" ury="780"/>
<char name="Edieresis" width="600" llx="25" lly="0" urx="670" ury="761"/>
<char name="Egrave" width="600" llx="25" lly="0" urx="670" ury="784"/>
<char name="Eth" width="600" llx="30" lly="0" urx="664" ury="562"/>
<char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="600" llx="39" lly="0" urx="684" ury="562"/>
<char name="G" width="600" llx="74" lly="-18" urx="675" ury="580"/>
<char name="H" width="600" llx="20" lly="0" urx="700" ury="562"/>
<char name="I" width="600" llx="77" lly="0" urx="643" ury="562"/>
<char name="Iacute" width="600" llx="77" lly="0" urx="643" ury="784"/>
<char name="Icircumflex" width="600" llx="77" lly="0" urx="643" ury="780"/>
<char name="Idieresis" width="600" llx="77" lly="0" urx="643" ury="761"/>
<char name="Igrave" width="600" llx="77" lly="0" urx="643" ury="784"/>
<char name="J" width="600" llx="58" lly="-18" urx="721" ury="562"/>
<char name="K" width="600" llx="21" lly="0" urx="692" ury="562"/>
<char name="L" width="600" llx="39" lly="0" urx="636" ury="562"/>
<char name="Lslash" width="600" llx="39" lly="0" urx="636" ury="562"/>
<char name="M" width="600" llx="-2" lly="0" urx="722" ury="562"/>
<char name="N" width="600" llx="8" lly="-12" urx="730" ury="562"/>
<char name="Ntilde" width="600" llx="8" lly="-12" urx="730" ury="759"/>
<char name="O" width="600" llx="74" lly="-18" urx="645" ury="580"/>
<char name="OE" width="600" llx="26" lly="0" urx="701" ury="562"/>
<char name="Oacute" width="600" llx="74" lly="-18" urx="645" ury="784"/>
<char name="Ocircumflex" width="600" llx="74" lly="-18" urx="645" ury="780"/>
<char name="Odieresis" width="600" llx="74" lly="-18" urx="645" ury="761"/>
<char name="Ograve" width="600" llx="74" lly="-18" urx="645" ury="784"/>
<char name="Oslash" width="600" llx="48" lly="-22" urx="673" ury="584"/>
<char name="Otilde" width="600" llx="74" lly="-18" urx="669" ury="759"/>
<char name="P" width="600" llx="48" lly="0" urx="643" ury="562"/>
<char name="Q" width="600" llx="83" lly="-138" urx="636" ury="580"/>
<char name="R" width="600" llx="24" lly="0" urx="617" ury="562"/>
<char name="S" width="600" llx="54" lly="-22" urx="673" ury="582"/>
<char name="Scaron" width="600" llx="54" lly="-22" urx="689" ury="790"/>
<char name="Scedilla" width="600" llx="54" lly="-206" urx="673" ury="582"/>
<char name="T" width="600" llx="86" lly="0" urx="679" ury="562"/>
<char name="Thorn" width="600" llx="48" lly="0" urx="620" ury="562"/>
<char name="U" width="600" llx="101" lly="-18" urx="716" ury="562"/>
<char name="Uacute" width="600" llx="101" lly="-18" urx="716" ury="784"/>
<char name="Ucircumflex" width="600" llx="101" lly="-18" urx="716" ury="780"/>
<char name="Udieresis" width="600" llx="101" lly="-18" urx="716" ury="761"/>
<char name="Ugrave" width="600" llx="101" lly="-18" urx="716" ury="784"/>
<char name="V" width="600" llx="84" lly="0" urx="733" ury="562"/>
<char name="W" width="600" llx="79" lly="0" urx="738" ury="562"/>
<char name="X" width="600" llx="12" lly="0" urx="690" ury="562"/>
<char name="Y" width="600" llx="109" lly="0" urx="709" ury="562"/>
<char name="Yacute" width="600" llx="109" lly="0" urx="709" ury="784"/>
<char name="Ydieresis" width="600" llx="109" lly="0" urx="709" ury="761"/>
<char name="Z" width="600" llx="62" lly="0" urx="637" ury="562"/>
<char name="Zcaron" width="600" llx="62" lly="0" urx="659" ury="790"/>
<char name="a" width="600" llx="61" lly="-15" urx="593" ury="454"/>
<char name="aacute" width="600" llx="61" lly="-15" urx="609" ury="661"/>
<char name="acircumflex" width="600" llx="61" lly="-15" urx="607" ury="657"/>
<char name="acute" width="600" llx="312" lly="508" urx="609" ury="661"/>
<char name="adieresis" width="600" llx="61" lly="-15" urx="595" ury="638"/>
<char name="ae" width="600" llx="21" lly="-15" urx="652" ury="454"/>
<char name="agrave" width="600" llx="61" lly="-15" urx="593" ury="661"/>
<char name="ampersand" width="600" llx="61" lly="-15" urx="595" ury="543"/>
<char name="aring" width="600" llx="61" lly="-15" urx="593" ury="678"/>
<char name="asciicircum" width="600" llx="171" lly="250" urx="556" ury="616"/>
<char name="asciitilde" width="600" llx="120" lly="153" urx="590" ury="356"/>
<char name="asterisk" width="600" llx="179" lly="219" urx="598" ury="601"/>
<char name="at" width="600" llx="65" lly="-15" urx="642" ury="616"/>
<char name="atilde" width="600" llx="61" lly="-15" urx="643" ury="636"/>
<char name="b" width="600" llx="13" lly="-15" urx="636" ury="626"/>
<char name="backslash" width="600" llx="222" lly="-77" urx="496" ury="626"/>
<char name="bar" width="600" llx="201" lly="-250" urx="505" ury="750"/>
<char name="braceleft" width="600" llx="203" lly="-102" urx="595" ury="616"/>
<char name="braceright" width="600" llx="114" lly="-102" urx="506" ury="616"/>
<char name="bracketleft" width="600" llx="223" lly="-102" urx="606" ury="616"/>
<char name="bracketright" width="600" llx="103" lly="-102" urx="486" ury="616"/>
<char name="breve" width="600" llx="217" lly="468" urx="652" ury="631"/>
<char name="brokenbar" width="600" llx="217" lly="-175" urx="489" ury="675"/>
<char name="bullet" width="600" llx="196" lly="132" urx="523" ury="430"/>
<char name="c" width="600" llx="81" lly="-15" urx="631" ury="459"/>
<char name="caron" width="600" llx="238" lly="493" urx="633" ury="667"/>
<char name="ccedilla" width="600" llx="81" lly="-206" urx="631" ury="459"/>
<char name="cedilla" width="600" llx="168" lly="-206" urx="368" ury="0"/>
<char name="cent" width="600" llx="121" lly="-49" urx="605" ury="614"/>
<char name="circumflex" width="600" llx="212" lly="483" urx="607" ury="657"/>
<char name="colon" width="600" llx="205" lly="-15" urx="480" ury="425"/>
<char name="comma" width="600" llx="99" lly="-111" urx="430" ury="174"/>
<char name="copyright" width="600" llx="53" lly="-18" urx="667" ury="580"/>
<char name="currency" width="600" llx="77" lly="49" urx="644" ury="517"/>
<char name="d" width="600" llx="60" lly="-15" urx="645" ury="626"/>
<char name="dagger" width="600" llx="175" lly="-70" urx="586" ury="580"/>
<char name="daggerdbl" width="600" llx="121" lly="-70" urx="587" ury="580"/>
<char name="degree" width="600" llx="173" lly="243" urx="570" ury="616"/>
<char name="dieresis" width="600" llx="246" lly="498" urx="595" ury="638"/>
<char name="divide" width="600" llx="114" lly="16" urx="596" ury="500"/>
<char name="dollar" width="600" llx="87" lly="-126" urx="630" ury="666"/>
<char name="dotaccent" width="600" llx="348" lly="498" urx="493" ury="638"/>
<char name="dotlessi" width="600" llx="77" lly="0" urx="546" ury="439"/>
<char name="e" width="600" llx="81" lly="-15" urx="605" ury="454"/>
<char name="eacute" width="600" llx="81" lly="-15" urx="609" ury="661"/>
<char name="ecircumflex" width="600" llx="81" lly="-15" urx="607" ury="657"/>
<char name="edieresis" width="600" llx="81" lly="-15" urx="605" ury="638"/>
<char name="egrave" width="600" llx="81" lly="-15" urx="605" ury="661"/>
<char name="eight" width="600" llx="115" lly="-15" urx="604" ury="616"/>
<char name="ellipsis" width="600" llx="35" lly="-15" urx="587" ury="116"/>
<char name="emdash" width="600" llx="33" lly="203" urx="677" ury="313"/>
<char name="endash" width="600" llx="108" lly="203" urx="602" ury="313"/>
<char name="equal" width="600" llx="96" lly="118" urx="614" ury="398"/>
<char name="eth" width="600" llx="93" lly="-27" urx="661" ury="626"/>
<char name="exclam" width="600" llx="215" lly="-15" urx="495" ury="572"/>
<char name="exclamdown" width="600" llx="196" lly="-146" urx="477" ury="449"/>
<char name="f" width="600" llx="83" lly="0" urx="677" ury="626"/>
<char name="fi" width="600" llx="12" lly="0" urx="644" ury="626"/>
<char name="five" width="600" llx="77" lly="-15" urx="621" ury="601"/>
<char name="fl" width="600" llx="12" lly="0" urx="644" ury="626"/>
<char name="florin" width="600" llx="-57" lly="-131" urx="702" ury="616"/>
<char name="four" width="600" llx="81" lly="0" urx="559" ury="616"/>
<char name="fraction" width="600" llx="22" lly="-60" urx="708" ury="661"/>
<char name="g" width="600" llx="40" lly="-146" urx="674" ury="454"/>
<char name="germandbls" width="600" llx="22" lly="-15" urx="629" ury="626"/>
<char name="grave" width="600" llx="272" lly="508" urx="503" ury="661"/>
<char name="greater" width="600" llx="97" lly="15" urx="589" ury="501"/>
<char name="guillemotleft" width="600" llx="62" lly="70" urx="639" ury="446"/>
<char name="guillemotright" width="600" llx="71" lly="70" urx="647" ury="446"/>
<char name="guilsinglleft" width="600" llx="195" lly="70" urx="545" ury="446"/>
<char name="guilsinglright" width="600" llx="165" lly="70" urx="514" ury="446"/>
<char name="h" width="600" llx="18" lly="0" urx="615" ury="626"/>
<char name="hungarumlaut" width="600" llx="171" lly="488" urx="729" ury="661"/>
<char name="hyphen" width="600" llx="143" lly="203" urx="567" ury="313"/>
<char name="i" width="600" llx="77" lly="0" urx="546" ury="658"/>
<char name="iacute" width="600" llx="77" lly="0" urx="609" ury="661"/>
<char name="icircumflex" width="600" llx="77" lly="0" urx="577" ury="657"/>
<char name="idieresis" width="600" llx="77" lly="0" urx="561" ury="618"/>
<char name="igrave" width="600" llx="77" lly="0" urx="546" ury="661"/>
<char name="j" width="600" llx="36" lly="-146" urx="580" ury="658"/>
<char name="k" width="600" llx="33" lly="0" urx="643" ury="626"/>
<char name="l" width="600" llx="77" lly="0" urx="546" ury="626"/>
<char name="less" width="600" llx="120" lly="15" urx="613" ury="501"/>
<char name="logicalnot" width="600" llx="135" lly="103" urx="617" ury="413"/>
<char name="lslash" width="600" llx="77" lly="0" urx="587" ury="626"/>
<char name="m" width="600" llx="-22" lly="0" urx="649" ury="454"/>
<char name="macron" width="600" llx="195" lly="505" urx="637" ury="585"/>
<char name="minus" width="600" llx="114" lly="203" urx="596" ury="313"/>
<char name="mu" width="600" llx="49" lly="-142" urx="592" ury="439"/>
<char name="multiply" width="600" llx="104" lly="39" urx="606" ury="478"/>
<char name="n" width="600" llx="18" lly="0" urx="615" ury="454"/>
<char name="nine" width="600" llx="75" lly="-15" urx="592" ury="616"/>
<char name="ntilde" width="600" llx="18" lly="0" urx="643" ury="636"/>
<char name="numbersign" width="600" llx="88" lly="-45" urx="641" ury="651"/>
<char name="o" width="600" llx="71" lly="-15" urx="622" ury="454"/>
<char name="oacute" width="600" llx="71" lly="-15" urx="649" ury="661"/>
<char name="ocircumflex" width="600" llx="71" lly="-15" urx="622" ury="657"/>
<char name="odieresis" width="600" llx="71" lly="-15" urx="622" ury="638"/>
<char name="oe" width="600" llx="18" lly="-15" urx="662" ury="454"/>
<char name="ogonek" width="600" llx="143" lly="-199" urx="367" ury="0"/>
<char name="ograve" width="600" llx="71" lly="-15" urx="622" ury="661"/>
<char name="one" width="600" llx="93" lly="0" urx="562" ury="616"/>
<char name="onehalf" width="600" llx="22" lly="-60" urx="716" ury="661"/>
<char name="onequarter" width="600" llx="13" lly="-60" urx="707" ury="661"/>
<char name="onesuperior" width="600" llx="212" lly="230" urx="514" ury="616"/>
<char name="ordfeminine" width="600" llx="188" lly="196" urx="526" ury="580"/>
<char name="ordmasculine" width="600" llx="188" lly="196" urx="543" ury="580"/>
<char name="oslash" width="600" llx="54" lly="-24" urx="638" ury="463"/>
<char name="otilde" width="600" llx="71" lly="-15" urx="643" ury="636"/>
<char name="p" width="600" llx="-32" lly="-142" urx="622" ury="454"/>
<char name="paragraph" width="600" llx="61" lly="-70" urx="700" ury="580"/>
<char name="parenleft" width="600" llx="265" lly="-102" urx="592" ury="616"/>
<char name="parenright" width="600" llx="117" lly="-102" urx="444" ury="616"/>
<char name="percent" width="600" llx="101" lly="-15" urx="625" ury="616"/>
<char name="period" width="600" llx="206" lly="-15" urx="427" ury="171"/>
<char name="periodcentered" width="600" llx="248" lly="165" urx="461" ury="351"/>
<char name="perthousand" width="600" llx="-45" lly="-15" urx="743" ury="616"/>
<char name="plus" width="600" llx="114" lly="39" urx="596" ury="478"/>
<char name="plusminus" width="600" llx="76" lly="24" urx="614" ury="515"/>
<char name="q" width="600" llx="60" lly="-142" urx="685" ury="454"/>
<char name="question" width="600" llx="183" lly="-14" urx="592" ury="580"/>
<char name="questiondown" width="600" llx="100" lly="-146" urx="509" ury="449"/>
<char name="quotedbl" width="600" llx="211" lly="277" urx="585" ury="562"/>
<char name="quotedblbase" width="600" llx="34" lly="-142" urx="560" ury="143"/>
<char name="quotedblleft" width="600" llx="190" lly="277" urx="594" ury="562"/>
<char name="quotedblright" width="600" llx="119" lly="277" urx="645" ury="562"/>
<char name="quoteleft" width="600" llx="297" lly="277" urx="487" ury="562"/>
<char name="quoteright" width="600" llx="229" lly="277" urx="543" ury="562"/>
<char name="quotesinglbase" width="600" llx="144" lly="-142" urx="458" ury="143"/>
<char name="quotesingle" width="600" llx="303" lly="277" urx="493" ury="562"/>
<char name="r" width="600" llx="47" lly="0" urx="655" ury="454"/>
<char name="registered" width="600" llx="53" lly="-18" urx="667" ury="580"/>
<char name="ring" width="600" llx="319" lly="481" urx="528" ury="678"/>
<char name="s" width="600" llx="66" lly="-17" urx="608" ury="459"/>
<char name="scaron" width="600" llx="66" lly="-17" urx="633" ury="667"/>
<char name="scedilla" width="600" llx="66" lly="-206" urx="608" ury="459"/>
<char name="section" width="600" llx="74" lly="-70" urx="620" ury="580"/>
<char name="semicolon" width="600" llx="99" lly="-111" urx="481" ury="425"/>
<char name="seven" width="600" llx="147" lly="0" urx="622" ury="601"/>
<char name="six" width="600" llx="135" lly="-15" urx="652" ury="616"/>
<char name="slash" width="600" llx="90" lly="-77" urx="626" ury="626"/>
<char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="600"/>
<char name="square" width="600"/>
<char name="sterling" width="600"/>
<char name="stop" width="600"/>
<char name="t" width="600"/>
<char name="tab" width="600"/>
<char name="thorn" width="600"/>
<char name="three" width="600"/>
<char name="threequarters" width="600"/>
<char name="threesuperior" width="600"/>
<char name="tilde" width="600"/>
<char name="trademark" width="600"/>
<char name="two" width="600"/>
<char name="twosuperior" width="600"/>
<char name="u" width="600"/>
<char name="uacute" width="600"/>
<char name="ucircumflex" width="600"/>
<char name="udieresis" width="600"/>
<char name="ugrave" width="600"/>
<char name="underscore" width="600"/>
<char name="up" width="600"/>
<char name="v" width="600"/>
<char name="w" width="600"/>
<char name="x" width="600"/>
<char name="y" width="600"/>
<char name="yacute" width="600"/>
<char name="ydieresis" width="600"/>
<char name="yen" width="600"/>
<char name="z" width="600"/>
<char name="zcaron" width="600"/>
<char name="zero" width="600"/>
</widths>
<char name="sterling" width="600" llx="106" lly="-28" urx="650" ury="611"/>
<char name="t" width="600" llx="118" lly="-15" urx="567" ury="562"/>
<char name="thorn" width="600" llx="-32" lly="-142" urx="622" ury="626"/>
<char name="three" width="600" llx="71" lly="-15" urx="571" ury="616"/>
<char name="threequarters" width="600" llx="8" lly="-60" urx="699" ury="661"/>
<char name="threesuperior" width="600" llx="193" lly="222" urx="526" ury="616"/>
<char name="tilde" width="600" llx="199" lly="493" urx="643" ury="636"/>
<char name="trademark" width="600" llx="86" lly="230" urx="869" ury="562"/>
<char name="two" width="600" llx="61" lly="0" urx="594" ury="616"/>
<char name="twosuperior" width="600" llx="191" lly="230" urx="542" ury="616"/>
<char name="u" width="600" llx="70" lly="-15" urx="592" ury="439"/>
<char name="uacute" width="600" llx="70" lly="-15" urx="599" ury="661"/>
<char name="ucircumflex" width="600" llx="70" lly="-15" urx="597" ury="657"/>
<char name="udieresis" width="600" llx="70" lly="-15" urx="595" ury="638"/>
<char name="ugrave" width="600" llx="70" lly="-15" urx="592" ury="661"/>
<char name="underscore" width="600" llx="-27" lly="-125" urx="585" ury="-75"/>
<char name="v" width="600" llx="70" lly="0" urx="695" ury="439"/>
<char name="w" width="600" llx="53" lly="0" urx="712" ury="439"/>
<char name="x" width="600" llx="6" lly="0" urx="671" ury="439"/>
<char name="y" width="600" llx="-21" lly="-142" urx="695" ury="439"/>
<char name="yacute" width="600" llx="-21" lly="-142" urx="695" ury="661"/>
<char name="ydieresis" width="600" llx="-21" lly="-142" urx="695" ury="638"/>
<char name="yen" width="600" llx="98" lly="0" urx="710" ury="562"/>
<char name="z" width="600" llx="81" lly="0" urx="614" ury="439"/>
<char name="zcaron" width="600" llx="81" lly="0" urx="643" ury="667"/>
<char name="zero" width="600" llx="135" lly="-15" urx="593" ury="616"/>
</char-metrics>
</font-metrics>

+ 236
- 265
src/codegen/fonts/CourierOblique.xml View File

@@ -22,275 +22,246 @@
<family-name>Courier</family-name>
<class-name>CourierOblique</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>562</cap-height>
<x-height>426</x-height>
<ascender>629</ascender>
<descender>-157</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="600"/>
<char name="AE" width="600"/>
<char name="Aacute" width="600"/>
<char name="Acircumflex" width="600"/>
<char name="Adieresis" width="600"/>
<char name="Agrave" width="600"/>
<char name="Aring" width="600"/>
<char name="Atilde" width="600"/>
<char name="B" width="600"/>
<char name="C" width="600"/>
<char name="Ccedilla" width="600"/>
<char name="D" width="600"/>
<char name="E" width="600"/>
<char name="Eacute" width="600"/>
<char name="Ecircumflex" width="600"/>
<char name="Edieresis" width="600"/>
<char name="Egrave" width="600"/>
<char name="Eth" width="600"/>
<char name="Euro" width="600"/>
<char name="F" width="600"/>
<char name="G" width="600"/>
<char name="Gcaron" width="600"/>
<char name="H" width="600"/>
<char name="I" width="600"/>
<char name="IJ" width="600"/>
<char name="Iacute" width="600"/>
<char name="Icircumflex" width="600"/>
<char name="Idieresis" width="600"/>
<char name="Idot" width="600"/>
<char name="Igrave" width="600"/>
<char name="J" width="600"/>
<char name="K" width="600"/>
<char name="L" width="600"/>
<char name="LL" width="600"/>
<char name="Lslash" width="600"/>
<char name="M" width="600"/>
<char name="N" width="600"/>
<char name="Ntilde" width="600"/>
<char name="O" width="600"/>
<char name="OE" width="600"/>
<char name="Oacute" width="600"/>
<char name="Ocircumflex" width="600"/>
<char name="Odieresis" width="600"/>
<char name="Ograve" width="600"/>
<char name="Oslash" width="600"/>
<char name="Otilde" width="600"/>
<char name="P" width="600"/>
<char name="Q" width="600"/>
<char name="R" width="600"/>
<char name="S" width="600"/>
<char name="Scaron" width="600"/>
<char name="Scedilla" width="600"/>
<char name="T" width="600"/>
<char name="Thorn" width="600"/>
<char name="U" width="600"/>
<char name="Uacute" width="600"/>
<char name="Ucircumflex" width="600"/>
<char name="Udieresis" width="600"/>
<char name="Ugrave" width="600"/>
<char name="V" width="600"/>
<char name="W" width="600"/>
<char name="X" width="600"/>
<char name="Y" width="600"/>
<char name="Yacute" width="600"/>
<char name="Ydieresis" width="600"/>
<char name="Z" width="600"/>
<char name="Zcaron" width="600"/>
<char name="a" width="600"/>
<char name="aacute" width="600"/>
<char name="acircumflex" width="600"/>
<char name="acute" width="600"/>
<char name="adieresis" width="600"/>
<char name="ae" width="600"/>
<char name="agrave" width="600"/>
<char name="ampersand" width="600"/>
<char name="aring" width="600"/>
<char name="arrowboth" width="600"/>
<char name="arrowdown" width="600"/>
<char name="arrowleft" width="600"/>
<char name="arrowright" width="600"/>
<char name="arrowup" width="600"/>
<char name="asciicircum" width="600"/>
<char name="asciitilde" width="600"/>
<char name="asterisk" width="600"/>
<char name="at" width="600"/>
<char name="atilde" width="600"/>
<char name="b" width="600"/>
<char name="backslash" width="600"/>
<char name="bar" width="600"/>
<char name="braceleft" width="600"/>
<char name="braceright" width="600"/>
<char name="bracketleft" width="600"/>
<char name="bracketright" width="600"/>
<char name="breve" width="600"/>
<char name="brokenbar" width="600"/>
<char name="bullet" width="600"/>
<char name="c" width="600"/>
<char name="caron" width="600"/>
<char name="ccedilla" width="600"/>
<char name="cedilla" width="600"/>
<char name="cent" width="600"/>
<char name="center" width="600"/>
<char name="circumflex" width="600"/>
<char name="colon" width="600"/>
<char name="comma" width="600"/>
<char name="copyright" width="600"/>
<char name="currency" width="600"/>
<char name="d" width="600"/>
<char name="dagger" width="600"/>
<char name="daggerdbl" width="600"/>
<char name="dectab" width="600"/>
<char name="degree" width="600"/>
<char name="dieresis" width="600"/>
<char name="divide" width="600"/>
<char name="dollar" width="600"/>
<char name="dotaccent" width="600"/>
<char name="dotlessi" width="600"/>
<char name="down" width="600"/>
<char name="e" width="600"/>
<char name="eacute" width="600"/>
<char name="ecircumflex" width="600"/>
<char name="edieresis" width="600"/>
<char name="egrave" width="600"/>
<char name="eight" width="600"/>
<char name="ellipsis" width="600"/>
<char name="emdash" width="600"/>
<char name="endash" width="600"/>
<char name="equal" width="600"/>
<char name="eth" width="600"/>
<char name="exclam" width="600"/>
<char name="exclamdown" width="600"/>
<char name="f" width="600"/>
<char name="fi" width="600"/>
<char name="five" width="600"/>
<char name="fl" width="600"/>
<char name="florin" width="600"/>
<char name="format" width="600"/>
<char name="four" width="600"/>
<char name="fraction" width="600"/>
<char name="g" width="600"/>
<char name="gcaron" width="600"/>
<char name="germandbls" width="600"/>
<char name="grave" width="600"/>
<char name="graybox" width="600"/>
<char name="greater" width="600"/>
<char name="guillemotleft" width="600"/>
<char name="guillemotright" width="600"/>
<char name="guilsinglleft" width="600"/>
<char name="guilsinglright" width="600"/>
<char name="h" width="600"/>
<char name="hungarumlaut" width="600"/>
<char name="hyphen" width="600"/>
<char name="i" width="600"/>
<char name="iacute" width="600"/>
<char name="icircumflex" width="600"/>
<char name="idieresis" width="600"/>
<char name="igrave" width="600"/>
<char name="ij" width="600"/>
<char name="indent" width="600"/>
<char name="j" width="600"/>
<char name="k" width="600"/>
<char name="l" width="600"/>
<char name="largebullet" width="600"/>
<char name="left" width="600"/>
<char name="less" width="600"/>
<char name="lira" width="600"/>
<char name="ll" width="600"/>
<char name="logicalnot" width="600"/>
<char name="lslash" width="600"/>
<char name="m" width="600"/>
<char name="macron" width="600"/>
<char name="merge" width="600"/>
<char name="minus" width="600"/>
<char name="mu" width="600"/>
<char name="multiply" width="600"/>
<char name="n" width="600"/>
<char name="nine" width="600"/>
<char name="notegraphic" width="600"/>
<char name="ntilde" width="600"/>
<char name="numbersign" width="600"/>
<char name="o" width="600"/>
<char name="oacute" width="600"/>
<char name="ocircumflex" width="600"/>
<char name="odieresis" width="600"/>
<char name="oe" width="600"/>
<char name="ogonek" width="600"/>
<char name="ograve" width="600"/>
<char name="one" width="600"/>
<char name="onehalf" width="600"/>
<char name="onequarter" width="600"/>
<char name="onesuperior" width="600"/>
<char name="ordfeminine" width="600"/>
<char name="ordmasculine" width="600"/>
<char name="oslash" width="600"/>
<char name="otilde" width="600"/>
<char name="overscore" width="600"/>
<char name="p" width="600"/>
<char name="paragraph" width="600"/>
<char name="parenleft" width="600"/>
<char name="parenright" width="600"/>
<char name="percent" width="600"/>
<char name="period" width="600"/>
<char name="periodcentered" width="600"/>
<char name="perthousand" width="600"/>
<char name="plus" width="600"/>
<char name="plusminus" width="600"/>
<char name="prescription" width="600"/>
<char name="q" width="600"/>
<char name="question" width="600"/>
<char name="questiondown" width="600"/>
<char name="quotedbl" width="600"/>
<char name="quotedblbase" width="600"/>
<char name="quotedblleft" width="600"/>
<char name="quotedblright" width="600"/>
<char name="quoteleft" width="600"/>
<char name="quoteright" width="600"/>
<char name="quotesinglbase" width="600"/>
<char name="quotesingle" width="600"/>
<char name="r" width="600"/>
<char name="registered" width="600"/>
<char name="return" width="600"/>
<char name="ring" width="600"/>
<char name="s" width="600"/>
<char name="scaron" width="600"/>
<char name="scedilla" width="600"/>
<char name="section" width="600"/>
<char name="semicolon" width="600"/>
<char name="seven" width="600"/>
<char name="six" width="600"/>
<char name="slash" width="600"/>
<char name="space" width="600"/>
<char-metrics>
<char name="A" width="600" llx="3" lly="0" urx="607" ury="562"/>
<char name="AE" width="600" llx="3" lly="0" urx="655" ury="562"/>
<char name="Aacute" width="600" llx="3" lly="0" urx="660" ury="805"/>
<char name="Acircumflex" width="600" llx="3" lly="0" urx="607" ury="787"/>
<char name="Adieresis" width="600" llx="3" lly="0" urx="607" ury="753"/>
<char name="Agrave" width="600" llx="3" lly="0" urx="607" ury="805"/>
<char name="Aring" width="600" llx="3" lly="0" urx="607" ury="750"/>
<char name="Atilde" width="600" llx="3" lly="0" urx="655" ury="729"/>
<char name="B" width="600" llx="43" lly="0" urx="616" ury="562"/>
<char name="C" width="600" llx="93" lly="-18" urx="655" ury="580"/>
<char name="Ccedilla" width="600" llx="93" lly="-151" urx="658" ury="580"/>
<char name="D" width="600" llx="43" lly="0" urx="645" ury="562"/>
<char name="E" width="600" llx="53" lly="0" urx="660" ury="562"/>
<char name="Eacute" width="600" llx="53" lly="0" urx="670" ury="805"/>
<char name="Ecircumflex" width="600" llx="53" lly="0" urx="660" ury="787"/>
<char name="Edieresis" width="600" llx="53" lly="0" urx="660" ury="753"/>
<char name="Egrave" width="600" llx="53" lly="0" urx="660" ury="805"/>
<char name="Eth" width="600" llx="43" lly="0" urx="645" ury="562"/>
<char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="600" llx="53" lly="0" urx="660" ury="562"/>
<char name="G" width="600" llx="83" lly="-18" urx="645" ury="580"/>
<char name="H" width="600" llx="32" lly="0" urx="687" ury="562"/>
<char name="I" width="600" llx="96" lly="0" urx="623" ury="562"/>
<char name="Iacute" width="600" llx="96" lly="0" urx="640" ury="805"/>
<char name="Icircumflex" width="600" llx="96" lly="0" urx="623" ury="787"/>
<char name="Idieresis" width="600" llx="96" lly="0" urx="623" ury="753"/>
<char name="Igrave" width="600" llx="96" lly="0" urx="623" ury="805"/>
<char name="J" width="600" llx="52" lly="-18" urx="685" ury="562"/>
<char name="K" width="600" llx="38" lly="0" urx="671" ury="562"/>
<char name="L" width="600" llx="47" lly="0" urx="607" ury="562"/>
<char name="Lslash" width="600" llx="47" lly="0" urx="607" ury="562"/>
<char name="M" width="600" llx="4" lly="0" urx="715" ury="562"/>
<char name="N" width="600" llx="7" lly="-13" urx="712" ury="562"/>
<char name="Ntilde" width="600" llx="7" lly="-13" urx="712" ury="729"/>
<char name="O" width="600" llx="94" lly="-18" urx="625" ury="580"/>
<char name="OE" width="600" llx="59" lly="0" urx="672" ury="562"/>
<char name="Oacute" width="600" llx="94" lly="-18" urx="640" ury="805"/>
<char name="Ocircumflex" width="600" llx="94" lly="-18" urx="625" ury="787"/>
<char name="Odieresis" width="600" llx="94" lly="-18" urx="625" ury="753"/>
<char name="Ograve" width="600" llx="94" lly="-18" urx="625" ury="805"/>
<char name="Oslash" width="600" llx="94" lly="-80" urx="625" ury="629"/>
<char name="Otilde" width="600" llx="94" lly="-18" urx="655" ury="729"/>
<char name="P" width="600" llx="79" lly="0" urx="644" ury="562"/>
<char name="Q" width="600" llx="95" lly="-138" urx="625" ury="580"/>
<char name="R" width="600" llx="38" lly="0" urx="598" ury="562"/>
<char name="S" width="600" llx="76" lly="-20" urx="650" ury="580"/>
<char name="Scaron" width="600" llx="76" lly="-20" urx="672" ury="802"/>
<char name="Scedilla" width="600" llx="76" lly="-151" urx="650" ury="580"/>
<char name="T" width="600" llx="108" lly="0" urx="665" ury="562"/>
<char name="Thorn" width="600" llx="79" lly="0" urx="606" ury="562"/>
<char name="U" width="600" llx="125" lly="-18" urx="702" ury="562"/>
<char name="Uacute" width="600" llx="125" lly="-18" urx="702" ury="805"/>
<char name="Ucircumflex" width="600" llx="125" lly="-18" urx="702" ury="787"/>
<char name="Udieresis" width="600" llx="125" lly="-18" urx="702" ury="753"/>
<char name="Ugrave" width="600" llx="125" lly="-18" urx="702" ury="805"/>
<char name="V" width="600" llx="105" lly="-13" urx="723" ury="562"/>
<char name="W" width="600" llx="106" lly="-13" urx="722" ury="562"/>
<char name="X" width="600" llx="23" lly="0" urx="675" ury="562"/>
<char name="Y" width="600" llx="133" lly="0" urx="695" ury="562"/>
<char name="Yacute" width="600" llx="133" lly="0" urx="695" ury="805"/>
<char name="Ydieresis" width="600" llx="133" lly="0" urx="695" ury="753"/>
<char name="Z" width="600" llx="86" lly="0" urx="610" ury="562"/>
<char name="Zcaron" width="600" llx="86" lly="0" urx="642" ury="802"/>
<char name="a" width="600" llx="76" lly="-15" urx="569" ury="441"/>
<char name="aacute" width="600" llx="76" lly="-15" urx="612" ury="672"/>
<char name="acircumflex" width="600" llx="76" lly="-15" urx="581" ury="654"/>
<char name="acute" width="600" llx="348" lly="497" urx="612" ury="672"/>
<char name="adieresis" width="600" llx="76" lly="-15" urx="575" ury="620"/>
<char name="ae" width="600" llx="41" lly="-15" urx="626" ury="441"/>
<char name="agrave" width="600" llx="76" lly="-15" urx="569" ury="672"/>
<char name="ampersand" width="600" llx="87" lly="-15" urx="580" ury="543"/>
<char name="aring" width="600" llx="76" lly="-15" urx="569" ury="627"/>
<char name="asciicircum" width="600" llx="175" lly="354" urx="587" ury="622"/>
<char name="asciitilde" width="600" llx="116" lly="197" urx="600" ury="320"/>
<char name="asterisk" width="600" llx="212" lly="257" urx="580" ury="607"/>
<char name="at" width="600" llx="127" lly="-15" urx="582" ury="622"/>
<char name="atilde" width="600" llx="76" lly="-15" urx="629" ury="606"/>
<char name="b" width="600" llx="29" lly="-15" urx="625" ury="629"/>
<char name="backslash" width="600" llx="249" lly="-80" urx="468" ury="629"/>
<char name="bar" width="600" llx="222" lly="-250" urx="485" ury="750"/>
<char name="braceleft" width="600" llx="233" lly="-108" urx="569" ury="622"/>
<char name="braceright" width="600" llx="140" lly="-108" urx="477" ury="622"/>
<char name="bracketleft" width="600" llx="246" lly="-108" urx="574" ury="622"/>
<char name="bracketright" width="600" llx="135" lly="-108" urx="463" ury="622"/>
<char name="breve" width="600" llx="279" lly="501" urx="576" ury="609"/>
<char name="brokenbar" width="600" llx="238" lly="-175" urx="469" ury="675"/>
<char name="bullet" width="600" llx="224" lly="130" urx="485" ury="383"/>
<char name="c" width="600" llx="106" lly="-15" urx="608" ury="441"/>
<char name="caron" width="600" llx="262" lly="492" urx="614" ury="669"/>
<char name="ccedilla" width="600" llx="106" lly="-151" urx="614" ury="441"/>
<char name="cedilla" width="600" llx="197" lly="-151" urx="344" ury="10"/>
<char name="cent" width="600" llx="151" lly="-49" urx="588" ury="614"/>
<char name="circumflex" width="600" llx="229" lly="477" urx="581" ury="654"/>
<char name="colon" width="600" llx="238" lly="-15" urx="441" ury="385"/>
<char name="comma" width="600" llx="157" lly="-112" urx="370" ury="122"/>
<char name="copyright" width="600" llx="53" lly="-18" urx="667" ury="580"/>
<char name="currency" width="600" llx="94" lly="58" urx="628" ury="506"/>
<char name="d" width="600" llx="85" lly="-15" urx="640" ury="629"/>
<char name="dagger" width="600" llx="217" lly="-78" urx="546" ury="580"/>
<char name="daggerdbl" width="600" llx="163" lly="-78" urx="546" ury="580"/>
<char name="degree" width="600" llx="214" lly="269" urx="576" ury="622"/>
<char name="dieresis" width="600" llx="272" lly="537" urx="579" ury="640"/>
<char name="divide" width="600" llx="136" lly="48" urx="573" ury="467"/>
<char name="dollar" width="600" llx="108" lly="-126" urx="596" ury="662"/>
<char name="dotaccent" width="600" llx="373" lly="537" urx="478" ury="640"/>
<char name="dotlessi" width="600" llx="95" lly="0" urx="515" ury="426"/>
<char name="e" width="600" llx="106" lly="-15" urx="598" ury="441"/>
<char name="eacute" width="600" llx="106" lly="-15" urx="612" ury="672"/>
<char name="ecircumflex" width="600" llx="106" lly="-15" urx="598" ury="654"/>
<char name="edieresis" width="600" llx="106" lly="-15" urx="598" ury="620"/>
<char name="egrave" width="600" llx="106" lly="-15" urx="598" ury="672"/>
<char name="eight" width="600" llx="132" lly="-15" urx="588" ury="622"/>
<char name="ellipsis" width="600" llx="46" lly="-15" urx="575" ury="111"/>
<char name="emdash" width="600" llx="49" lly="231" urx="661" ury="285"/>
<char name="endash" width="600" llx="124" lly="231" urx="586" ury="285"/>
<char name="equal" width="600" llx="109" lly="138" urx="600" ury="376"/>
<char name="eth" width="600" llx="102" lly="-15" urx="639" ury="629"/>
<char name="exclam" width="600" llx="243" lly="-15" urx="464" ury="572"/>
<char name="exclamdown" width="600" llx="225" lly="-157" urx="445" ury="430"/>
<char name="f" width="600" llx="114" lly="0" urx="662" ury="629"/>
<char name="fi" width="600" llx="3" lly="0" urx="619" ury="629"/>
<char name="five" width="600" llx="99" lly="-15" urx="589" ury="607"/>
<char name="fl" width="600" llx="3" lly="0" urx="619" ury="629"/>
<char name="florin" width="600" llx="-26" lly="-143" urx="671" ury="622"/>
<char name="four" width="600" llx="108" lly="0" urx="541" ury="622"/>
<char name="fraction" width="600" llx="84" lly="-57" urx="646" ury="665"/>
<char name="g" width="600" llx="61" lly="-157" urx="657" ury="441"/>
<char name="germandbls" width="600" llx="48" lly="-15" urx="617" ury="629"/>
<char name="grave" width="600" llx="294" lly="497" urx="484" ury="672"/>
<char name="greater" width="600" llx="85" lly="42" urx="599" ury="472"/>
<char name="guillemotleft" width="600" llx="92" lly="70" urx="652" ury="446"/>
<char name="guillemotright" width="600" llx="58" lly="70" urx="618" ury="446"/>
<char name="guilsinglleft" width="600" llx="204" lly="70" urx="540" ury="446"/>
<char name="guilsinglright" width="600" llx="170" lly="70" urx="506" ury="446"/>
<char name="h" width="600" llx="33" lly="0" urx="592" ury="629"/>
<char name="hungarumlaut" width="600" llx="239" lly="497" urx="683" ury="672"/>
<char name="hyphen" width="600" llx="152" lly="231" urx="558" ury="285"/>
<char name="i" width="600" llx="95" lly="0" urx="515" ury="657"/>
<char name="iacute" width="600" llx="95" lly="0" urx="612" ury="672"/>
<char name="icircumflex" width="600" llx="95" lly="0" urx="551" ury="654"/>
<char name="idieresis" width="600" llx="95" lly="0" urx="545" ury="620"/>
<char name="igrave" width="600" llx="95" lly="0" urx="515" ury="672"/>
<char name="j" width="600" llx="52" lly="-157" urx="550" ury="657"/>
<char name="k" width="600" llx="58" lly="0" urx="633" ury="629"/>
<char name="l" width="600" llx="95" lly="0" urx="515" ury="629"/>
<char name="less" width="600" llx="96" lly="42" urx="610" ury="472"/>
<char name="logicalnot" width="600" llx="155" lly="108" urx="591" ury="369"/>
<char name="lslash" width="600" llx="95" lly="0" urx="587" ury="629"/>
<char name="m" width="600" llx="-5" lly="0" urx="615" ury="441"/>
<char name="macron" width="600" llx="232" lly="525" urx="600" ury="565"/>
<char name="minus" width="600" llx="129" lly="232" urx="580" ury="283"/>
<char name="mu" width="600" llx="72" lly="-157" urx="572" ury="426"/>
<char name="multiply" width="600" llx="103" lly="43" urx="607" ury="470"/>
<char name="n" width="600" llx="26" lly="0" urx="585" ury="441"/>
<char name="nine" width="600" llx="93" lly="-15" urx="574" ury="622"/>
<char name="ntilde" width="600" llx="26" lly="0" urx="629" ury="606"/>
<char name="numbersign" width="600" llx="133" lly="-32" urx="596" ury="639"/>
<char name="o" width="600" llx="102" lly="-15" urx="588" ury="441"/>
<char name="oacute" width="600" llx="102" lly="-15" urx="612" ury="672"/>
<char name="ocircumflex" width="600" llx="102" lly="-15" urx="588" ury="654"/>
<char name="odieresis" width="600" llx="102" lly="-15" urx="588" ury="620"/>
<char name="oe" width="600" llx="54" lly="-15" urx="615" ury="441"/>
<char name="ogonek" width="600" llx="189" lly="-172" urx="377" ury="4"/>
<char name="ograve" width="600" llx="102" lly="-15" urx="588" ury="672"/>
<char name="one" width="600" llx="98" lly="0" urx="515" ury="622"/>
<char name="onehalf" width="600" llx="65" lly="-57" urx="669" ury="665"/>
<char name="onequarter" width="600" llx="65" lly="-57" urx="674" ury="665"/>
<char name="onesuperior" width="600" llx="231" lly="249" urx="491" ury="622"/>
<char name="ordfeminine" width="600" llx="209" lly="249" urx="512" ury="580"/>
<char name="ordmasculine" width="600" llx="210" lly="249" urx="535" ury="580"/>
<char name="oslash" width="600" llx="102" lly="-80" urx="588" ury="506"/>
<char name="otilde" width="600" llx="102" lly="-15" urx="629" ury="606"/>
<char name="p" width="600" llx="-24" lly="-157" urx="605" ury="441"/>
<char name="paragraph" width="600" llx="100" lly="-78" urx="630" ury="562"/>
<char name="parenleft" width="600" llx="313" lly="-108" urx="572" ury="622"/>
<char name="parenright" width="600" llx="137" lly="-108" urx="396" ury="622"/>
<char name="percent" width="600" llx="134" lly="-15" urx="599" ury="622"/>
<char name="period" width="600" llx="238" lly="-15" urx="382" ury="109"/>
<char name="periodcentered" width="600" llx="275" lly="189" urx="434" ury="327"/>
<char name="perthousand" width="600" llx="59" lly="-15" urx="627" ury="622"/>
<char name="plus" width="600" llx="129" lly="44" urx="580" ury="470"/>
<char name="plusminus" width="600" llx="96" lly="44" urx="594" ury="558"/>
<char name="q" width="600" llx="85" lly="-157" urx="682" ury="441"/>
<char name="question" width="600" llx="222" lly="-15" urx="583" ury="572"/>
<char name="questiondown" width="600" llx="105" lly="-157" urx="466" ury="430"/>
<char name="quotedbl" width="600" llx="273" lly="328" urx="532" ury="562"/>
<char name="quotedblbase" width="600" llx="115" lly="-134" urx="478" ury="100"/>
<char name="quotedblleft" width="600" llx="262" lly="328" urx="541" ury="562"/>
<char name="quotedblright" width="600" llx="213" lly="328" urx="576" ury="562"/>
<char name="quoteleft" width="600" llx="343" lly="328" urx="457" ury="562"/>
<char name="quoteright" width="600" llx="283" lly="328" urx="495" ury="562"/>
<char name="quotesinglbase" width="600" llx="185" lly="-134" urx="397" ury="100"/>
<char name="quotesingle" width="600" llx="345" lly="328" urx="460" ury="562"/>
<char name="r" width="600" llx="60" lly="0" urx="636" ury="441"/>
<char name="registered" width="600" llx="53" lly="-18" urx="667" ury="580"/>
<char name="ring" width="600" llx="332" lly="463" urx="500" ury="627"/>
<char name="s" width="600" llx="78" lly="-15" urx="584" ury="441"/>
<char name="scaron" width="600" llx="78" lly="-15" urx="614" ury="669"/>
<char name="scedilla" width="600" llx="78" lly="-151" urx="584" ury="441"/>
<char name="section" width="600" llx="104" lly="-78" urx="590" ury="580"/>
<char name="semicolon" width="600" llx="157" lly="-112" urx="441" ury="385"/>
<char name="seven" width="600" llx="182" lly="0" urx="612" ury="607"/>
<char name="six" width="600" llx="155" lly="-15" urx="629" ury="622"/>
<char name="slash" width="600" llx="112" lly="-80" urx="604" ury="629"/>
<char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="600"/>
<char name="square" width="600"/>
<char name="sterling" width="600"/>
<char name="stop" width="600"/>
<char name="t" width="600"/>
<char name="tab" width="600"/>
<char name="thorn" width="600"/>
<char name="three" width="600"/>
<char name="threequarters" width="600"/>
<char name="threesuperior" width="600"/>
<char name="tilde" width="600"/>
<char name="trademark" width="600"/>
<char name="two" width="600"/>
<char name="twosuperior" width="600"/>
<char name="u" width="600"/>
<char name="uacute" width="600"/>
<char name="ucircumflex" width="600"/>
<char name="udieresis" width="600"/>
<char name="ugrave" width="600"/>
<char name="underscore" width="600"/>
<char name="up" width="600"/>
<char name="v" width="600"/>
<char name="w" width="600"/>
<char name="x" width="600"/>
<char name="y" width="600"/>
<char name="yacute" width="600"/>
<char name="ydieresis" width="600"/>
<char name="yen" width="600"/>
<char name="z" width="600"/>
<char name="zcaron" width="600"/>
<char name="zero" width="600"/>
</widths>
</font-metrics>
<char name="sterling" width="600" llx="124" lly="-21" urx="621" ury="611"/>
<char name="t" width="600" llx="167" lly="-15" urx="561" ury="561"/>
<char name="thorn" width="600" llx="-24" lly="-157" urx="605" ury="629"/>
<char name="three" width="600" llx="82" lly="-15" urx="538" ury="622"/>
<char name="threequarters" width="600" llx="73" lly="-56" urx="659" ury="666"/>
<char name="threesuperior" width="600" llx="213" lly="240" urx="501" ury="622"/>
<char name="tilde" width="600" llx="212" lly="489" urx="629" ury="606"/>
<char name="trademark" width="600" llx="75" lly="263" urx="742" ury="562"/>
<char name="two" width="600" llx="70" lly="0" urx="568" ury="622"/>
<char name="twosuperior" width="600" llx="230" lly="249" urx="535" ury="622"/>
<char name="u" width="600" llx="101" lly="-15" urx="572" ury="426"/>
<char name="uacute" width="600" llx="101" lly="-15" urx="602" ury="672"/>
<char name="ucircumflex" width="600" llx="101" lly="-15" urx="572" ury="654"/>
<char name="udieresis" width="600" llx="101" lly="-15" urx="575" ury="620"/>
<char name="ugrave" width="600" llx="101" lly="-15" urx="572" ury="672"/>
<char name="underscore" width="600" llx="-27" lly="-125" urx="584" ury="-75"/>
<char name="v" width="600" llx="90" lly="-10" urx="681" ury="426"/>
<char name="w" width="600" llx="76" lly="-10" urx="695" ury="426"/>
<char name="x" width="600" llx="20" lly="0" urx="655" ury="426"/>
<char name="y" width="600" llx="-4" lly="-157" urx="683" ury="426"/>
<char name="yacute" width="600" llx="-4" lly="-157" urx="683" ury="672"/>
<char name="ydieresis" width="600" llx="-4" lly="-157" urx="683" ury="620"/>
<char name="yen" width="600" llx="120" lly="0" urx="693" ury="562"/>
<char name="z" width="600" llx="99" lly="0" urx="593" ury="426"/>
<char name="zcaron" width="600" llx="99" lly="0" urx="624" ury="669"/>
<char name="zero" width="600" llx="154" lly="-15" urx="575" ury="622"/>
</char-metrics>
</font-metrics>

+ 233
- 232
src/codegen/fonts/Helvetica.xml View File

@@ -22,245 +22,246 @@
<family-name>Helvetica</family-name>
<class-name>Helvetica</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>718</cap-height>
<x-height>523</x-height>
<ascender>718</ascender>
<descender>-207</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="667"/>
<char name="AE" width="1000"/>
<char name="Aacute" width="667"/>
<char name="Acircumflex" width="667"/>
<char name="Adieresis" width="667"/>
<char name="Agrave" width="667"/>
<char name="Aring" width="667"/>
<char name="Atilde" width="667"/>
<char name="B" width="667"/>
<char name="C" width="722"/>
<char name="Ccedilla" width="722"/>
<char name="D" width="722"/>
<char name="E" width="667"/>
<char name="Eacute" width="667"/>
<char name="Ecircumflex" width="667"/>
<char name="Edieresis" width="667"/>
<char name="Egrave" width="667"/>
<char name="Eth" width="722"/>
<char name="Euro" width="556"/>
<char name="F" width="611"/>
<char name="G" width="778"/>
<char name="H" width="722"/>
<char name="I" width="278"/>
<char name="Iacute" width="278"/>
<char name="Icircumflex" width="278"/>
<char name="Idieresis" width="278"/>
<char name="Igrave" width="278"/>
<char name="J" width="500"/>
<char name="K" width="667"/>
<char name="L" width="556"/>
<char name="Lslash" width="556"/>
<char name="M" width="833"/>
<char name="N" width="722"/>
<char name="Ntilde" width="722"/>
<char name="O" width="778"/>
<char name="OE" width="1000"/>
<char name="Oacute" width="778"/>
<char name="Ocircumflex" width="778"/>
<char name="Odieresis" width="778"/>
<char name="Ograve" width="778"/>
<char name="Oslash" width="778"/>
<char name="Otilde" width="778"/>
<char name="P" width="667"/>
<char name="Q" width="778"/>
<char name="R" width="722"/>
<char name="S" width="667"/>
<char name="Scaron" width="667"/>
<char name="T" width="611"/>
<char name="Thorn" width="667"/>
<char name="U" width="722"/>
<char name="Uacute" width="722"/>
<char name="Ucircumflex" width="722"/>
<char name="Udieresis" width="722"/>
<char name="Ugrave" width="722"/>
<char name="V" width="667"/>
<char name="W" width="944"/>
<char name="X" width="667"/>
<char name="Y" width="667"/>
<char name="Yacute" width="667"/>
<char name="Ydieresis" width="667"/>
<char name="Z" width="611"/>
<char name="Zcaron" width="611"/>
<char name="a" width="556"/>
<char name="aacute" width="556"/>
<char name="acircumflex" width="556"/>
<char name="acute" width="333"/>
<char name="adieresis" width="556"/>
<char name="ae" width="889"/>
<char name="agrave" width="556"/>
<char name="ampersand" width="667"/>
<char name="aring" width="556"/>
<char name="asciicircum" width="469"/>
<char name="asciitilde" width="584"/>
<char name="asterisk" width="389"/>
<char name="at" width="1015"/>
<char name="atilde" width="556"/>
<char name="b" width="556"/>
<char name="backslash" width="278"/>
<char name="bar" width="260"/>
<char name="braceleft" width="334"/>
<char name="braceright" width="334"/>
<char name="bracketleft" width="278"/>
<char name="bracketright" width="278"/>
<char name="breve" width="333"/>
<char name="brokenbar" width="260"/>
<char name="bullet" width="350"/>
<char name="c" width="500"/>
<char name="caron" width="333"/>
<char name="ccedilla" width="500"/>
<char name="cedilla" width="333"/>
<char name="cent" width="556"/>
<char name="circumflex" width="333"/>
<char name="colon" width="278"/>
<char name="comma" width="278"/>
<char name="copyright" width="737"/>
<char name="currency" width="556"/>
<char name="d" width="556"/>
<char name="dagger" width="556"/>
<char name="daggerdbl" width="556"/>
<char name="degree" width="400"/>
<char name="dieresis" width="333"/>
<char name="divide" width="584"/>
<char name="dollar" width="556"/>
<char name="dotaccent" width="333"/>
<char name="dotlessi" width="278"/>
<char name="e" width="556"/>
<char name="eacute" width="556"/>
<char name="ecircumflex" width="556"/>
<char name="edieresis" width="556"/>
<char name="egrave" width="556"/>
<char name="eight" width="556"/>
<char name="ellipsis" width="1000"/>
<char name="emdash" width="1000"/>
<char name="endash" width="556"/>
<char name="equal" width="584"/>
<char name="eth" width="556"/>
<char name="exclam" width="278"/>
<char name="exclamdown" width="333"/>
<char name="f" width="278"/>
<char name="fi" width="500"/>
<char name="five" width="556"/>
<char name="fl" width="500"/>
<char name="florin" width="556"/>
<char name="four" width="556"/>
<char name="fraction" width="167"/>
<char name="g" width="556"/>
<char name="germandbls" width="611"/>
<char name="grave" width="333"/>
<char name="greater" width="584"/>
<char name="guillemotleft" width="556"/>
<char name="guillemotright" width="556"/>
<char name="guilsinglleft" width="333"/>
<char name="guilsinglright" width="333"/>
<char name="h" width="556"/>
<char name="hungarumlaut" width="333"/>
<char name="hyphen" width="333"/>
<char name="i" width="222"/>
<char name="iacute" width="278"/>
<char name="icircumflex" width="278"/>
<char name="idieresis" width="278"/>
<char name="igrave" width="278"/>
<char name="j" width="222"/>
<char name="k" width="500"/>
<char name="l" width="222"/>
<char name="less" width="584"/>
<char name="logicalnot" width="584"/>
<char name="lslash" width="222"/>
<char name="m" width="833"/>
<char name="macron" width="333"/>
<char name="minus" width="324"/>
<char name="mu" width="556"/>
<char name="multiply" width="584"/>
<char name="n" width="556"/>
<char name="nine" width="556"/>
<char name="ntilde" width="556"/>
<char name="numbersign" width="556"/>
<char name="o" width="556"/>
<char name="oacute" width="556"/>
<char name="ocircumflex" width="556"/>
<char name="odieresis" width="556"/>
<char name="oe" width="944"/>
<char name="ogonek" width="333"/>
<char name="ograve" width="556"/>
<char name="one" width="556"/>
<char name="onehalf" width="834"/>
<char name="onequarter" width="834"/>
<char name="onesuperior" width="333"/>
<char name="ordfeminine" width="370"/>
<char name="ordmasculine" width="365"/>
<char name="oslash" width="611"/>
<char name="otilde" width="556"/>
<char name="p" width="556"/>
<char name="paragraph" width="537"/>
<char name="parenleft" width="333"/>
<char name="parenright" width="333"/>
<char name="percent" width="889"/>
<char name="period" width="278"/>
<char name="periodcentered" width="278"/>
<char name="perthousand" width="1000"/>
<char name="plus" width="584"/>
<char name="plusminus" width="584"/>
<char name="q" width="556"/>
<char name="question" width="556"/>
<char name="questiondown" width="611"/>
<char name="quotedbl" width="355"/>
<char name="quotedblbase" width="333"/>
<char name="quotedblleft" width="333"/>
<char name="quotedblright" width="333"/>
<char name="quoteleft" width="222"/>
<char name="quoteright" width="222"/>
<char name="quotesinglbase" width="222"/>
<char name="quotesingle" width="191"/>
<char name="r" width="333"/>
<char name="registered" width="737"/>
<char name="ring" width="333"/>
<char name="s" width="500"/>
<char name="scaron" width="500"/>
<char name="section" width="556"/>
<char name="semicolon" width="278"/>
<char name="seven" width="556"/>
<char name="six" width="556"/>
<char name="slash" width="278"/>
<char name="space" width="278"/>
<char-metrics>
<char name="A" width="667" llx="14" lly="0" urx="654" ury="718"/>
<char name="AE" width="1000" llx="8" lly="0" urx="951" ury="718"/>
<char name="Aacute" width="667" llx="14" lly="0" urx="654" ury="929"/>
<char name="Acircumflex" width="667" llx="14" lly="0" urx="654" ury="929"/>
<char name="Adieresis" width="667" llx="14" lly="0" urx="654" ury="901"/>
<char name="Agrave" width="667" llx="14" lly="0" urx="654" ury="929"/>
<char name="Aring" width="667" llx="14" lly="0" urx="654" ury="931"/>
<char name="Atilde" width="667" llx="14" lly="0" urx="654" ury="917"/>
<char name="B" width="667" llx="74" lly="0" urx="627" ury="718"/>
<char name="C" width="722" llx="44" lly="-19" urx="681" ury="737"/>
<char name="Ccedilla" width="722" llx="44" lly="-225" urx="681" ury="737"/>
<char name="D" width="722" llx="81" lly="0" urx="674" ury="718"/>
<char name="E" width="667" llx="86" lly="0" urx="616" ury="718"/>
<char name="Eacute" width="667" llx="86" lly="0" urx="616" ury="929"/>
<char name="Ecircumflex" width="667" llx="86" lly="0" urx="616" ury="929"/>
<char name="Edieresis" width="667" llx="86" lly="0" urx="616" ury="901"/>
<char name="Egrave" width="667" llx="86" lly="0" urx="616" ury="929"/>
<char name="Eth" width="722" llx="0" lly="0" urx="674" ury="718"/>
<char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="611" llx="86" lly="0" urx="583" ury="718"/>
<char name="G" width="778" llx="48" lly="-19" urx="704" ury="737"/>
<char name="H" width="722" llx="77" lly="0" urx="646" ury="718"/>
<char name="I" width="278" llx="91" lly="0" urx="188" ury="718"/>
<char name="Iacute" width="278" llx="91" lly="0" urx="292" ury="929"/>
<char name="Icircumflex" width="278" llx="-6" lly="0" urx="285" ury="929"/>
<char name="Idieresis" width="278" llx="13" lly="0" urx="266" ury="901"/>
<char name="Igrave" width="278" llx="-13" lly="0" urx="188" ury="929"/>
<char name="J" width="500" llx="17" lly="-19" urx="428" ury="718"/>
<char name="K" width="667" llx="76" lly="0" urx="663" ury="718"/>
<char name="L" width="556" llx="76" lly="0" urx="537" ury="718"/>
<char name="Lslash" width="556" llx="-20" lly="0" urx="537" ury="718"/>
<char name="M" width="833" llx="73" lly="0" urx="761" ury="718"/>
<char name="N" width="722" llx="76" lly="0" urx="646" ury="718"/>
<char name="Ntilde" width="722" llx="76" lly="0" urx="646" ury="917"/>
<char name="O" width="778" llx="39" lly="-19" urx="739" ury="737"/>
<char name="OE" width="1000" llx="36" lly="-19" urx="965" ury="737"/>
<char name="Oacute" width="778" llx="39" lly="-19" urx="739" ury="929"/>
<char name="Ocircumflex" width="778" llx="39" lly="-19" urx="739" ury="929"/>
<char name="Odieresis" width="778" llx="39" lly="-19" urx="739" ury="901"/>
<char name="Ograve" width="778" llx="39" lly="-19" urx="739" ury="929"/>
<char name="Oslash" width="778" llx="39" lly="-19" urx="740" ury="737"/>
<char name="Otilde" width="778" llx="39" lly="-19" urx="739" ury="917"/>
<char name="P" width="667" llx="86" lly="0" urx="622" ury="718"/>
<char name="Q" width="778" llx="39" lly="-56" urx="739" ury="737"/>
<char name="R" width="722" llx="88" lly="0" urx="684" ury="718"/>
<char name="S" width="667" llx="49" lly="-19" urx="620" ury="737"/>
<char name="Scaron" width="667" llx="49" lly="-19" urx="620" ury="929"/>
<char name="T" width="611" llx="14" lly="0" urx="597" ury="718"/>
<char name="Thorn" width="667" llx="86" lly="0" urx="622" ury="718"/>
<char name="U" width="722" llx="79" lly="-19" urx="644" ury="718"/>
<char name="Uacute" width="722" llx="79" lly="-19" urx="644" ury="929"/>
<char name="Ucircumflex" width="722" llx="79" lly="-19" urx="644" ury="929"/>
<char name="Udieresis" width="722" llx="79" lly="-19" urx="644" ury="901"/>
<char name="Ugrave" width="722" llx="79" lly="-19" urx="644" ury="929"/>
<char name="V" width="667" llx="20" lly="0" urx="647" ury="718"/>
<char name="W" width="944" llx="16" lly="0" urx="928" ury="718"/>
<char name="X" width="667" llx="19" lly="0" urx="648" ury="718"/>
<char name="Y" width="667" llx="14" lly="0" urx="653" ury="718"/>
<char name="Yacute" width="667" llx="14" lly="0" urx="653" ury="929"/>
<char name="Ydieresis" width="667" llx="14" lly="0" urx="653" ury="901"/>
<char name="Z" width="611" llx="23" lly="0" urx="588" ury="718"/>
<char name="Zcaron" width="611" llx="23" lly="0" urx="588" ury="929"/>
<char name="a" width="556" llx="36" lly="-15" urx="530" ury="538"/>
<char name="aacute" width="556" llx="36" lly="-15" urx="530" ury="734"/>
<char name="acircumflex" width="556" llx="36" lly="-15" urx="530" ury="734"/>
<char name="acute" width="333" llx="122" lly="593" urx="319" ury="734"/>
<char name="adieresis" width="556" llx="36" lly="-15" urx="530" ury="706"/>
<char name="ae" width="889" llx="36" lly="-15" urx="847" ury="538"/>
<char name="agrave" width="556" llx="36" lly="-15" urx="530" ury="734"/>
<char name="ampersand" width="667" llx="44" lly="-15" urx="645" ury="718"/>
<char name="aring" width="556" llx="36" lly="-15" urx="530" ury="756"/>
<char name="asciicircum" width="469" llx="-14" lly="264" urx="483" ury="688"/>
<char name="asciitilde" width="584" llx="61" lly="180" urx="523" ury="326"/>
<char name="asterisk" width="389" llx="39" lly="431" urx="349" ury="718"/>
<char name="at" width="1015" llx="147" lly="-19" urx="868" ury="737"/>
<char name="atilde" width="556" llx="36" lly="-15" urx="530" ury="722"/>
<char name="b" width="556" llx="58" lly="-15" urx="517" ury="718"/>
<char name="backslash" width="278" llx="-17" lly="-19" urx="295" ury="737"/>
<char name="bar" width="260" llx="94" lly="-225" urx="167" ury="775"/>
<char name="braceleft" width="334" llx="42" lly="-196" urx="292" ury="722"/>
<char name="braceright" width="334" llx="42" lly="-196" urx="292" ury="722"/>
<char name="bracketleft" width="278" llx="63" lly="-196" urx="250" ury="722"/>
<char name="bracketright" width="278" llx="28" lly="-196" urx="215" ury="722"/>
<char name="breve" width="333" llx="13" lly="595" urx="321" ury="731"/>
<char name="brokenbar" width="260" llx="94" lly="-150" urx="167" ury="700"/>
<char name="bullet" width="350" llx="18" lly="202" urx="333" ury="517"/>
<char name="c" width="500" llx="30" lly="-15" urx="477" ury="538"/>
<char name="caron" width="333" llx="21" lly="593" urx="312" ury="734"/>
<char name="ccedilla" width="500" llx="30" lly="-225" urx="477" ury="538"/>
<char name="cedilla" width="333" llx="45" lly="-225" urx="259" ury="0"/>
<char name="cent" width="556" llx="51" lly="-115" urx="513" ury="623"/>
<char name="circumflex" width="333" llx="21" lly="593" urx="312" ury="734"/>
<char name="colon" width="278" llx="87" lly="0" urx="191" ury="516"/>
<char name="comma" width="278" llx="87" lly="-147" urx="191" ury="106"/>
<char name="copyright" width="737" llx="-14" lly="-19" urx="752" ury="737"/>
<char name="currency" width="556" llx="28" lly="99" urx="528" ury="603"/>
<char name="d" width="556" llx="35" lly="-15" urx="499" ury="718"/>
<char name="dagger" width="556" llx="43" lly="-159" urx="514" ury="718"/>
<char name="daggerdbl" width="556" llx="43" lly="-159" urx="514" ury="718"/>
<char name="degree" width="400" llx="54" lly="411" urx="346" ury="703"/>
<char name="dieresis" width="333" llx="40" lly="604" urx="293" ury="706"/>
<char name="divide" width="584" llx="39" lly="-19" urx="545" ury="524"/>
<char name="dollar" width="556" llx="32" lly="-115" urx="520" ury="775"/>
<char name="dotaccent" width="333" llx="121" lly="604" urx="212" ury="706"/>
<char name="dotlessi" width="278" llx="95" lly="0" urx="183" ury="523"/>
<char name="e" width="556" llx="40" lly="-15" urx="516" ury="538"/>
<char name="eacute" width="556" llx="40" lly="-15" urx="516" ury="734"/>
<char name="ecircumflex" width="556" llx="40" lly="-15" urx="516" ury="734"/>
<char name="edieresis" width="556" llx="40" lly="-15" urx="516" ury="706"/>
<char name="egrave" width="556" llx="40" lly="-15" urx="516" ury="734"/>
<char name="eight" width="556" llx="38" lly="-19" urx="517" ury="703"/>
<char name="ellipsis" width="1000" llx="115" lly="0" urx="885" ury="106"/>
<char name="emdash" width="1000" llx="0" lly="240" urx="1000" ury="313"/>
<char name="endash" width="556" llx="0" lly="240" urx="556" ury="313"/>
<char name="equal" width="584" llx="39" lly="115" urx="545" ury="390"/>
<char name="eth" width="556" llx="35" lly="-15" urx="522" ury="737"/>
<char name="exclam" width="278" llx="90" lly="0" urx="187" ury="718"/>
<char name="exclamdown" width="333" llx="118" lly="-195" urx="215" ury="523"/>
<char name="f" width="278" llx="14" lly="0" urx="262" ury="728"/>
<char name="fi" width="500" llx="14" lly="0" urx="434" ury="728"/>
<char name="five" width="556" llx="32" lly="-19" urx="514" ury="688"/>
<char name="fl" width="500" llx="14" lly="0" urx="432" ury="728"/>
<char name="florin" width="556" llx="-11" lly="-207" urx="501" ury="737"/>
<char name="four" width="556" llx="25" lly="0" urx="523" ury="703"/>
<char name="fraction" width="167" llx="-166" lly="-19" urx="333" ury="703"/>
<char name="g" width="556" llx="40" lly="-220" urx="499" ury="538"/>
<char name="germandbls" width="611" llx="67" lly="-15" urx="571" ury="728"/>
<char name="grave" width="333" llx="14" lly="593" urx="211" ury="734"/>
<char name="greater" width="584" llx="48" lly="11" urx="536" ury="495"/>
<char name="guillemotleft" width="556" llx="97" lly="108" urx="459" ury="446"/>
<char name="guillemotright" width="556" llx="97" lly="108" urx="459" ury="446"/>
<char name="guilsinglleft" width="333" llx="88" lly="108" urx="245" ury="446"/>
<char name="guilsinglright" width="333" llx="88" lly="108" urx="245" ury="446"/>
<char name="h" width="556" llx="65" lly="0" urx="491" ury="718"/>
<char name="hungarumlaut" width="333" llx="31" lly="593" urx="409" ury="734"/>
<char name="hyphen" width="333" llx="44" lly="232" urx="289" ury="322"/>
<char name="i" width="222" llx="67" lly="0" urx="155" ury="718"/>
<char name="iacute" width="278" llx="95" lly="0" urx="292" ury="734"/>
<char name="icircumflex" width="278" llx="-6" lly="0" urx="285" ury="734"/>
<char name="idieresis" width="278" llx="13" lly="0" urx="266" ury="706"/>
<char name="igrave" width="278" llx="-13" lly="0" urx="184" ury="734"/>
<char name="j" width="222" llx="-16" lly="-210" urx="155" ury="718"/>
<char name="k" width="500" llx="67" lly="0" urx="501" ury="718"/>
<char name="l" width="222" llx="67" lly="0" urx="155" ury="718"/>
<char name="less" width="584" llx="48" lly="11" urx="536" ury="495"/>
<char name="logicalnot" width="584" llx="39" lly="108" urx="545" ury="390"/>
<char name="lslash" width="222" llx="-20" lly="0" urx="242" ury="718"/>
<char name="m" width="833" llx="65" lly="0" urx="769" ury="538"/>
<char name="macron" width="333" llx="10" lly="627" urx="323" ury="684"/>
<char name="minus" width="324" llx="39" lly="216" urx="545" ury="289"/>
<char name="mu" width="556" llx="68" lly="-207" urx="489" ury="523"/>
<char name="multiply" width="584" llx="39" lly="0" urx="545" ury="506"/>
<char name="n" width="556" llx="65" lly="0" urx="491" ury="538"/>
<char name="nine" width="556" llx="42" lly="-19" urx="514" ury="703"/>
<char name="ntilde" width="556" llx="65" lly="0" urx="491" ury="722"/>
<char name="numbersign" width="556" llx="28" lly="0" urx="529" ury="688"/>
<char name="o" width="556" llx="35" lly="-14" urx="521" ury="538"/>
<char name="oacute" width="556" llx="35" lly="-14" urx="521" ury="734"/>
<char name="ocircumflex" width="556" llx="35" lly="-14" urx="521" ury="734"/>
<char name="odieresis" width="556" llx="35" lly="-14" urx="521" ury="706"/>
<char name="oe" width="944" llx="35" lly="-15" urx="902" ury="538"/>
<char name="ogonek" width="333" llx="73" lly="-225" urx="287" ury="0"/>
<char name="ograve" width="556" llx="35" lly="-14" urx="521" ury="734"/>
<char name="one" width="556" llx="101" lly="0" urx="359" ury="703"/>
<char name="onehalf" width="834" llx="43" lly="-19" urx="773" ury="703"/>
<char name="onequarter" width="834" llx="73" lly="-19" urx="756" ury="703"/>
<char name="onesuperior" width="333" llx="43" lly="281" urx="222" ury="703"/>
<char name="ordfeminine" width="370" llx="24" lly="405" urx="346" ury="737"/>
<char name="ordmasculine" width="365" llx="25" lly="405" urx="341" ury="737"/>
<char name="oslash" width="611" llx="28" lly="-22" urx="537" ury="545"/>
<char name="otilde" width="556" llx="35" lly="-14" urx="521" ury="722"/>
<char name="p" width="556" llx="58" lly="-207" urx="517" ury="538"/>
<char name="paragraph" width="537" llx="18" lly="-173" urx="497" ury="718"/>
<char name="parenleft" width="333" llx="68" lly="-207" urx="299" ury="733"/>
<char name="parenright" width="333" llx="34" lly="-207" urx="265" ury="733"/>
<char name="percent" width="889" llx="39" lly="-19" urx="850" ury="703"/>
<char name="period" width="278" llx="87" lly="0" urx="191" ury="106"/>
<char name="periodcentered" width="278" llx="77" lly="190" urx="202" ury="315"/>
<char name="perthousand" width="1000" llx="7" lly="-19" urx="994" ury="703"/>
<char name="plus" width="584" llx="39" lly="0" urx="545" ury="505"/>
<char name="plusminus" width="584" llx="39" lly="0" urx="545" ury="506"/>
<char name="q" width="556" llx="35" lly="-207" urx="494" ury="538"/>
<char name="question" width="556" llx="56" lly="0" urx="492" ury="727"/>
<char name="questiondown" width="611" llx="91" lly="-201" urx="527" ury="525"/>
<char name="quotedbl" width="355" llx="70" lly="463" urx="285" ury="718"/>
<char name="quotedblbase" width="333" llx="26" lly="-149" urx="295" ury="106"/>
<char name="quotedblleft" width="333" llx="38" lly="470" urx="307" ury="725"/>
<char name="quotedblright" width="333" llx="26" lly="463" urx="295" ury="718"/>
<char name="quoteleft" width="222" llx="65" lly="470" urx="169" ury="725"/>
<char name="quoteright" width="222" llx="53" lly="463" urx="157" ury="718"/>
<char name="quotesinglbase" width="222" llx="53" lly="-149" urx="157" ury="106"/>
<char name="quotesingle" width="191" llx="59" lly="463" urx="132" ury="718"/>
<char name="r" width="333" llx="77" lly="0" urx="332" ury="538"/>
<char name="registered" width="737" llx="-14" lly="-19" urx="752" ury="737"/>
<char name="ring" width="333" llx="75" lly="572" urx="259" ury="756"/>
<char name="s" width="500" llx="32" lly="-15" urx="464" ury="538"/>
<char name="scaron" width="500" llx="32" lly="-15" urx="464" ury="734"/>
<char name="section" width="556" llx="43" lly="-191" urx="512" ury="737"/>
<char name="semicolon" width="278" llx="87" lly="-147" urx="191" ury="516"/>
<char name="seven" width="556" llx="37" lly="0" urx="523" ury="688"/>
<char name="six" width="556" llx="38" lly="-19" urx="518" ury="703"/>
<char name="slash" width="278" llx="-17" lly="-19" urx="295" ury="737"/>
<char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="278"/>
<char name="sterling" width="556"/>
<char name="t" width="278"/>
<char name="thorn" width="556"/>
<char name="three" width="556"/>
<char name="threequarters" width="834"/>
<char name="threesuperior" width="333"/>
<char name="tilde" width="333"/>
<char name="trademark" width="1000"/>
<char name="two" width="556"/>
<char name="twosuperior" width="333"/>
<char name="u" width="556"/>
<char name="uacute" width="556"/>
<char name="ucircumflex" width="556"/>
<char name="udieresis" width="556"/>
<char name="ugrave" width="556"/>
<char name="underscore" width="556"/>
<char name="v" width="500"/>
<char name="w" width="722"/>
<char name="x" width="500"/>
<char name="y" width="500"/>
<char name="yacute" width="500"/>
<char name="ydieresis" width="500"/>
<char name="yen" width="556"/>
<char name="z" width="500"/>
<char name="zcaron" width="500"/>
<char name="zero" width="556"/>
</widths>
<char name="sterling" width="556" llx="33" lly="-16" urx="539" ury="718"/>
<char name="t" width="278" llx="14" lly="-7" urx="257" ury="669"/>
<char name="thorn" width="556" llx="58" lly="-207" urx="517" ury="718"/>
<char name="three" width="556" llx="34" lly="-19" urx="522" ury="703"/>
<char name="threequarters" width="834" llx="45" lly="-19" urx="810" ury="703"/>
<char name="threesuperior" width="333" llx="5" lly="270" urx="325" ury="703"/>
<char name="tilde" width="333" llx="-4" lly="606" urx="337" ury="722"/>
<char name="trademark" width="1000" llx="46" lly="306" urx="903" ury="718"/>
<char name="two" width="556" llx="26" lly="0" urx="507" ury="703"/>
<char name="twosuperior" width="333" llx="4" lly="281" urx="323" ury="703"/>
<char name="u" width="556" llx="68" lly="-15" urx="489" ury="523"/>
<char name="uacute" width="556" llx="68" lly="-15" urx="489" ury="734"/>
<char name="ucircumflex" width="556" llx="68" lly="-15" urx="489" ury="734"/>
<char name="udieresis" width="556" llx="68" lly="-15" urx="489" ury="706"/>
<char name="ugrave" width="556" llx="68" lly="-15" urx="489" ury="734"/>
<char name="underscore" width="556" llx="0" lly="-125" urx="556" ury="-75"/>
<char name="v" width="500" llx="8" lly="0" urx="492" ury="523"/>
<char name="w" width="722" llx="14" lly="0" urx="709" ury="523"/>
<char name="x" width="500" llx="11" lly="0" urx="490" ury="523"/>
<char name="y" width="500" llx="11" lly="-214" urx="489" ury="523"/>
<char name="yacute" width="500" llx="11" lly="-214" urx="489" ury="734"/>
<char name="ydieresis" width="500" llx="11" lly="-214" urx="489" ury="706"/>
<char name="yen" width="556" llx="3" lly="0" urx="553" ury="688"/>
<char name="z" width="500" llx="31" lly="0" urx="469" ury="523"/>
<char name="zcaron" width="500" llx="31" lly="0" urx="469" ury="734"/>
<char name="zero" width="556" llx="37" lly="-19" urx="519" ury="703"/>
</char-metrics>
<kerning kpx1="107">
<pair kern="-20" kpx2="111"/>
<pair kern="-20" kpx2="101"/>

+ 233
- 232
src/codegen/fonts/HelveticaBold.xml View File

@@ -22,245 +22,246 @@
<family-name>Helvetica</family-name>
<class-name>HelveticaBold</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>718</cap-height>
<x-height>532</x-height>
<ascender>718</ascender>
<descender>-207</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="722"/>
<char name="AE" width="1000"/>
<char name="Aacute" width="722"/>
<char name="Acircumflex" width="722"/>
<char name="Adieresis" width="722"/>
<char name="Agrave" width="722"/>
<char name="Aring" width="722"/>
<char name="Atilde" width="722"/>
<char name="B" width="722"/>
<char name="C" width="722"/>
<char name="Ccedilla" width="722"/>
<char name="D" width="722"/>
<char name="E" width="667"/>
<char name="Eacute" width="667"/>
<char name="Ecircumflex" width="667"/>
<char name="Edieresis" width="667"/>
<char name="Egrave" width="667"/>
<char name="Eth" width="722"/>
<char name="Euro" width="556"/>
<char name="F" width="611"/>
<char name="G" width="778"/>
<char name="H" width="722"/>
<char name="I" width="278"/>
<char name="Iacute" width="278"/>
<char name="Icircumflex" width="278"/>
<char name="Idieresis" width="278"/>
<char name="Igrave" width="278"/>
<char name="J" width="556"/>
<char name="K" width="722"/>
<char name="L" width="611"/>
<char name="Lslash" width="611"/>
<char name="M" width="833"/>
<char name="N" width="722"/>
<char name="Ntilde" width="722"/>
<char name="O" width="778"/>
<char name="OE" width="1000"/>
<char name="Oacute" width="778"/>
<char name="Ocircumflex" width="778"/>
<char name="Odieresis" width="778"/>
<char name="Ograve" width="778"/>
<char name="Oslash" width="778"/>
<char name="Otilde" width="778"/>
<char name="P" width="667"/>
<char name="Q" width="778"/>
<char name="R" width="722"/>
<char name="S" width="667"/>
<char name="Scaron" width="667"/>
<char name="T" width="611"/>
<char name="Thorn" width="667"/>
<char name="U" width="722"/>
<char name="Uacute" width="722"/>
<char name="Ucircumflex" width="722"/>
<char name="Udieresis" width="722"/>
<char name="Ugrave" width="722"/>
<char name="V" width="667"/>
<char name="W" width="944"/>
<char name="X" width="667"/>
<char name="Y" width="667"/>
<char name="Yacute" width="667"/>
<char name="Ydieresis" width="667"/>
<char name="Z" width="611"/>
<char name="Zcaron" width="611"/>
<char name="a" width="556"/>
<char name="aacute" width="556"/>
<char name="acircumflex" width="556"/>
<char name="acute" width="333"/>
<char name="adieresis" width="556"/>
<char name="ae" width="889"/>
<char name="agrave" width="556"/>
<char name="ampersand" width="722"/>
<char name="aring" width="556"/>
<char name="asciicircum" width="584"/>
<char name="asciitilde" width="584"/>
<char name="asterisk" width="389"/>
<char name="at" width="975"/>
<char name="atilde" width="556"/>
<char name="b" width="611"/>
<char name="backslash" width="278"/>
<char name="bar" width="280"/>
<char name="braceleft" width="389"/>
<char name="braceright" width="389"/>
<char name="bracketleft" width="333"/>
<char name="bracketright" width="333"/>
<char name="breve" width="333"/>
<char name="brokenbar" width="280"/>
<char name="bullet" width="350"/>
<char name="c" width="556"/>
<char name="caron" width="333"/>
<char name="ccedilla" width="556"/>
<char name="cedilla" width="333"/>
<char name="cent" width="556"/>
<char name="circumflex" width="333"/>
<char name="colon" width="333"/>
<char name="comma" width="278"/>
<char name="copyright" width="737"/>
<char name="currency" width="556"/>
<char name="d" width="611"/>
<char name="dagger" width="556"/>
<char name="daggerdbl" width="556"/>
<char name="degree" width="400"/>
<char name="dieresis" width="333"/>
<char name="divide" width="584"/>
<char name="dollar" width="556"/>
<char name="dotaccent" width="333"/>
<char name="dotlessi" width="278"/>
<char name="e" width="556"/>
<char name="eacute" width="556"/>
<char name="ecircumflex" width="556"/>
<char name="edieresis" width="556"/>
<char name="egrave" width="556"/>
<char name="eight" width="556"/>
<char name="ellipsis" width="1000"/>
<char name="emdash" width="1000"/>
<char name="endash" width="556"/>
<char name="equal" width="584"/>
<char name="eth" width="611"/>
<char name="exclam" width="333"/>
<char name="exclamdown" width="333"/>
<char name="f" width="333"/>
<char name="fi" width="611"/>
<char name="five" width="556"/>
<char name="fl" width="611"/>
<char name="florin" width="556"/>
<char name="four" width="556"/>
<char name="fraction" width="167"/>
<char name="g" width="611"/>
<char name="germandbls" width="611"/>
<char name="grave" width="333"/>
<char name="greater" width="584"/>
<char name="guillemotleft" width="556"/>
<char name="guillemotright" width="556"/>
<char name="guilsinglleft" width="333"/>
<char name="guilsinglright" width="333"/>
<char name="h" width="611"/>
<char name="hungarumlaut" width="333"/>
<char name="hyphen" width="333"/>
<char name="i" width="278"/>
<char name="iacute" width="278"/>
<char name="icircumflex" width="278"/>
<char name="idieresis" width="278"/>
<char name="igrave" width="278"/>
<char name="j" width="278"/>
<char name="k" width="556"/>
<char name="l" width="278"/>
<char name="less" width="584"/>
<char name="logicalnot" width="584"/>
<char name="lslash" width="278"/>
<char name="m" width="889"/>
<char name="macron" width="333"/>
<char name="minus" width="324"/>
<char name="mu" width="611"/>
<char name="multiply" width="584"/>
<char name="n" width="611"/>
<char name="nine" width="556"/>
<char name="ntilde" width="611"/>
<char name="numbersign" width="556"/>
<char name="o" width="611"/>
<char name="oacute" width="611"/>
<char name="ocircumflex" width="611"/>
<char name="odieresis" width="611"/>
<char name="oe" width="944"/>
<char name="ogonek" width="333"/>
<char name="ograve" width="611"/>
<char name="one" width="556"/>
<char name="onehalf" width="834"/>
<char name="onequarter" width="834"/>
<char name="onesuperior" width="333"/>
<char name="ordfeminine" width="370"/>
<char name="ordmasculine" width="365"/>
<char name="oslash" width="611"/>
<char name="otilde" width="611"/>
<char name="p" width="611"/>
<char name="paragraph" width="556"/>
<char name="parenleft" width="333"/>
<char name="parenright" width="333"/>
<char name="percent" width="889"/>
<char name="period" width="278"/>
<char name="periodcentered" width="278"/>
<char name="perthousand" width="1000"/>
<char name="plus" width="584"/>
<char name="plusminus" width="584"/>
<char name="q" width="611"/>
<char name="question" width="611"/>
<char name="questiondown" width="611"/>
<char name="quotedbl" width="474"/>
<char name="quotedblbase" width="500"/>
<char name="quotedblleft" width="500"/>
<char name="quotedblright" width="500"/>
<char name="quoteleft" width="278"/>
<char name="quoteright" width="278"/>
<char name="quotesinglbase" width="278"/>
<char name="quotesingle" width="238"/>
<char name="r" width="389"/>
<char name="registered" width="737"/>
<char name="ring" width="333"/>
<char name="s" width="556"/>
<char name="scaron" width="556"/>
<char name="section" width="556"/>
<char name="semicolon" width="333"/>
<char name="seven" width="556"/>
<char name="six" width="556"/>
<char name="slash" width="278"/>
<char name="space" width="278"/>
<char-metrics>
<char name="A" width="722" llx="20" lly="0" urx="702" ury="718"/>
<char name="AE" width="1000" llx="5" lly="0" urx="954" ury="718"/>
<char name="Aacute" width="722" llx="20" lly="0" urx="702" ury="936"/>
<char name="Acircumflex" width="722" llx="20" lly="0" urx="702" ury="936"/>
<char name="Adieresis" width="722" llx="20" lly="0" urx="702" ury="915"/>
<char name="Agrave" width="722" llx="20" lly="0" urx="702" ury="936"/>
<char name="Aring" width="722" llx="20" lly="0" urx="702" ury="962"/>
<char name="Atilde" width="722" llx="20" lly="0" urx="702" ury="923"/>
<char name="B" width="722" llx="76" lly="0" urx="669" ury="718"/>
<char name="C" width="722" llx="44" lly="-19" urx="684" ury="737"/>
<char name="Ccedilla" width="722" llx="44" lly="-228" urx="684" ury="737"/>
<char name="D" width="722" llx="76" lly="0" urx="685" ury="718"/>
<char name="E" width="667" llx="76" lly="0" urx="621" ury="718"/>
<char name="Eacute" width="667" llx="76" lly="0" urx="621" ury="936"/>
<char name="Ecircumflex" width="667" llx="76" lly="0" urx="621" ury="936"/>
<char name="Edieresis" width="667" llx="76" lly="0" urx="621" ury="915"/>
<char name="Egrave" width="667" llx="76" lly="0" urx="621" ury="936"/>
<char name="Eth" width="722" llx="-5" lly="0" urx="685" ury="718"/>
<char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="611" llx="76" lly="0" urx="587" ury="718"/>
<char name="G" width="778" llx="44" lly="-19" urx="713" ury="737"/>
<char name="H" width="722" llx="71" lly="0" urx="651" ury="718"/>
<char name="I" width="278" llx="64" lly="0" urx="214" ury="718"/>
<char name="Iacute" width="278" llx="64" lly="0" urx="329" ury="936"/>
<char name="Icircumflex" width="278" llx="-37" lly="0" urx="316" ury="936"/>
<char name="Idieresis" width="278" llx="-21" lly="0" urx="300" ury="915"/>
<char name="Igrave" width="278" llx="-50" lly="0" urx="214" ury="936"/>
<char name="J" width="556" llx="22" lly="-18" urx="484" ury="718"/>
<char name="K" width="722" llx="87" lly="0" urx="722" ury="718"/>
<char name="L" width="611" llx="76" lly="0" urx="583" ury="718"/>
<char name="Lslash" width="611" llx="-20" lly="0" urx="583" ury="718"/>
<char name="M" width="833" llx="69" lly="0" urx="765" ury="718"/>
<char name="N" width="722" llx="69" lly="0" urx="654" ury="718"/>
<char name="Ntilde" width="722" llx="69" lly="0" urx="654" ury="923"/>
<char name="O" width="778" llx="44" lly="-19" urx="734" ury="737"/>
<char name="OE" width="1000" llx="37" lly="-19" urx="961" ury="737"/>
<char name="Oacute" width="778" llx="44" lly="-19" urx="734" ury="936"/>
<char name="Ocircumflex" width="778" llx="44" lly="-19" urx="734" ury="936"/>
<char name="Odieresis" width="778" llx="44" lly="-19" urx="734" ury="915"/>
<char name="Ograve" width="778" llx="44" lly="-19" urx="734" ury="936"/>
<char name="Oslash" width="778" llx="33" lly="-27" urx="744" ury="745"/>
<char name="Otilde" width="778" llx="44" lly="-19" urx="734" ury="923"/>
<char name="P" width="667" llx="76" lly="0" urx="627" ury="718"/>
<char name="Q" width="778" llx="44" lly="-52" urx="737" ury="737"/>
<char name="R" width="722" llx="76" lly="0" urx="677" ury="718"/>
<char name="S" width="667" llx="39" lly="-19" urx="629" ury="737"/>
<char name="Scaron" width="667" llx="39" lly="-19" urx="629" ury="936"/>
<char name="T" width="611" llx="14" lly="0" urx="598" ury="718"/>
<char name="Thorn" width="667" llx="76" lly="0" urx="627" ury="718"/>
<char name="U" width="722" llx="72" lly="-19" urx="651" ury="718"/>
<char name="Uacute" width="722" llx="72" lly="-19" urx="651" ury="936"/>
<char name="Ucircumflex" width="722" llx="72" lly="-19" urx="651" ury="936"/>
<char name="Udieresis" width="722" llx="72" lly="-19" urx="651" ury="915"/>
<char name="Ugrave" width="722" llx="72" lly="-19" urx="651" ury="936"/>
<char name="V" width="667" llx="19" lly="0" urx="648" ury="718"/>
<char name="W" width="944" llx="16" lly="0" urx="929" ury="718"/>
<char name="X" width="667" llx="14" lly="0" urx="653" ury="718"/>
<char name="Y" width="667" llx="15" lly="0" urx="653" ury="718"/>
<char name="Yacute" width="667" llx="15" lly="0" urx="653" ury="936"/>
<char name="Ydieresis" width="667" llx="15" lly="0" urx="653" ury="915"/>
<char name="Z" width="611" llx="25" lly="0" urx="586" ury="718"/>
<char name="Zcaron" width="611" llx="25" lly="0" urx="586" ury="936"/>
<char name="a" width="556" llx="29" lly="-14" urx="527" ury="546"/>
<char name="aacute" width="556" llx="29" lly="-14" urx="527" ury="750"/>
<char name="acircumflex" width="556" llx="29" lly="-14" urx="527" ury="750"/>
<char name="acute" width="333" llx="108" lly="604" urx="356" ury="750"/>
<char name="adieresis" width="556" llx="29" lly="-14" urx="527" ury="729"/>
<char name="ae" width="889" llx="29" lly="-14" urx="858" ury="546"/>
<char name="agrave" width="556" llx="29" lly="-14" urx="527" ury="750"/>
<char name="ampersand" width="722" llx="54" lly="-19" urx="701" ury="718"/>
<char name="aring" width="556" llx="29" lly="-14" urx="527" ury="776"/>
<char name="asciicircum" width="584" llx="62" lly="323" urx="522" ury="698"/>
<char name="asciitilde" width="584" llx="61" lly="163" urx="523" ury="343"/>
<char name="asterisk" width="389" llx="27" lly="387" urx="362" ury="718"/>
<char name="at" width="975" llx="118" lly="-19" urx="856" ury="737"/>
<char name="atilde" width="556" llx="29" lly="-14" urx="527" ury="737"/>
<char name="b" width="611" llx="61" lly="-14" urx="578" ury="718"/>
<char name="backslash" width="278" llx="-33" lly="-19" urx="311" ury="737"/>
<char name="bar" width="280" llx="84" lly="-225" urx="196" ury="775"/>
<char name="braceleft" width="389" llx="48" lly="-196" urx="365" ury="722"/>
<char name="braceright" width="389" llx="24" lly="-196" urx="341" ury="722"/>
<char name="bracketleft" width="333" llx="63" lly="-196" urx="309" ury="722"/>
<char name="bracketright" width="333" llx="24" lly="-196" urx="270" ury="722"/>
<char name="breve" width="333" llx="-2" lly="604" urx="335" ury="750"/>
<char name="brokenbar" width="280" llx="84" lly="-150" urx="196" ury="700"/>
<char name="bullet" width="350" llx="10" lly="194" urx="340" ury="524"/>
<char name="c" width="556" llx="34" lly="-14" urx="524" ury="546"/>
<char name="caron" width="333" llx="-10" lly="604" urx="343" ury="750"/>
<char name="ccedilla" width="556" llx="34" lly="-228" urx="524" ury="546"/>
<char name="cedilla" width="333" llx="6" lly="-228" urx="245" ury="0"/>
<char name="cent" width="556" llx="34" lly="-118" urx="524" ury="628"/>
<char name="circumflex" width="333" llx="-10" lly="604" urx="343" ury="750"/>
<char name="colon" width="333" llx="92" lly="0" urx="242" ury="512"/>
<char name="comma" width="278" llx="64" lly="-168" urx="214" ury="146"/>
<char name="copyright" width="737" llx="-11" lly="-19" urx="749" ury="737"/>
<char name="currency" width="556" llx="-3" lly="76" urx="559" ury="636"/>
<char name="d" width="611" llx="34" lly="-14" urx="551" ury="718"/>
<char name="dagger" width="556" llx="36" lly="-171" urx="520" ury="718"/>
<char name="daggerdbl" width="556" llx="36" lly="-171" urx="520" ury="718"/>
<char name="degree" width="400" llx="57" lly="426" urx="343" ury="712"/>
<char name="dieresis" width="333" llx="6" lly="614" urx="327" ury="729"/>
<char name="divide" width="584" llx="40" lly="-42" urx="544" ury="548"/>
<char name="dollar" width="556" llx="30" lly="-115" urx="523" ury="775"/>
<char name="dotaccent" width="333" llx="104" lly="614" urx="230" ury="729"/>
<char name="dotlessi" width="278" llx="69" lly="0" urx="209" ury="532"/>
<char name="e" width="556" llx="23" lly="-14" urx="528" ury="546"/>
<char name="eacute" width="556" llx="23" lly="-14" urx="528" ury="750"/>
<char name="ecircumflex" width="556" llx="23" lly="-14" urx="528" ury="750"/>
<char name="edieresis" width="556" llx="23" lly="-14" urx="528" ury="729"/>
<char name="egrave" width="556" llx="23" lly="-14" urx="528" ury="750"/>
<char name="eight" width="556" llx="32" lly="-19" urx="524" ury="710"/>
<char name="ellipsis" width="1000" llx="92" lly="0" urx="908" ury="146"/>
<char name="emdash" width="1000" llx="0" lly="227" urx="1000" ury="333"/>
<char name="endash" width="556" llx="0" lly="227" urx="556" ury="333"/>
<char name="equal" width="584" llx="40" lly="87" urx="544" ury="419"/>
<char name="eth" width="611" llx="34" lly="-14" urx="578" ury="737"/>
<char name="exclam" width="333" llx="90" lly="0" urx="244" ury="718"/>
<char name="exclamdown" width="333" llx="90" lly="-186" urx="244" ury="532"/>
<char name="f" width="333" llx="10" lly="0" urx="318" ury="727"/>
<char name="fi" width="611" llx="10" lly="0" urx="542" ury="727"/>
<char name="five" width="556" llx="27" lly="-19" urx="516" ury="698"/>
<char name="fl" width="611" llx="10" lly="0" urx="542" ury="727"/>
<char name="florin" width="556" llx="-10" lly="-210" urx="516" ury="737"/>
<char name="four" width="556" llx="27" lly="0" urx="526" ury="710"/>
<char name="fraction" width="167" llx="-170" lly="-19" urx="336" ury="710"/>
<char name="g" width="611" llx="40" lly="-217" urx="553" ury="546"/>
<char name="germandbls" width="611" llx="69" lly="-14" urx="579" ury="731"/>
<char name="grave" width="333" llx="-23" lly="604" urx="225" ury="750"/>
<char name="greater" width="584" llx="38" lly="-8" urx="546" ury="514"/>
<char name="guillemotleft" width="556" llx="88" lly="76" urx="468" ury="484"/>
<char name="guillemotright" width="556" llx="88" lly="76" urx="468" ury="484"/>
<char name="guilsinglleft" width="333" llx="83" lly="76" urx="250" ury="484"/>
<char name="guilsinglright" width="333" llx="83" lly="76" urx="250" ury="484"/>
<char name="h" width="611" llx="65" lly="0" urx="546" ury="718"/>
<char name="hungarumlaut" width="333" llx="9" lly="604" urx="486" ury="750"/>
<char name="hyphen" width="333" llx="27" lly="215" urx="306" ury="345"/>
<char name="i" width="278" llx="69" lly="0" urx="209" ury="725"/>
<char name="iacute" width="278" llx="69" lly="0" urx="329" ury="750"/>
<char name="icircumflex" width="278" llx="-37" lly="0" urx="316" ury="750"/>
<char name="idieresis" width="278" llx="-21" lly="0" urx="300" ury="729"/>
<char name="igrave" width="278" llx="-50" lly="0" urx="209" ury="750"/>
<char name="j" width="278" llx="3" lly="-214" urx="209" ury="725"/>
<char name="k" width="556" llx="69" lly="0" urx="562" ury="718"/>
<char name="l" width="278" llx="69" lly="0" urx="209" ury="718"/>
<char name="less" width="584" llx="38" lly="-8" urx="546" ury="514"/>
<char name="logicalnot" width="584" llx="40" lly="108" urx="544" ury="419"/>
<char name="lslash" width="278" llx="-18" lly="0" urx="296" ury="718"/>
<char name="m" width="889" llx="64" lly="0" urx="826" ury="546"/>
<char name="macron" width="333" llx="-6" lly="604" urx="339" ury="678"/>
<char name="minus" width="324" llx="40" lly="197" urx="544" ury="309"/>
<char name="mu" width="611" llx="66" lly="-207" urx="545" ury="532"/>
<char name="multiply" width="584" llx="40" lly="1" urx="545" ury="505"/>
<char name="n" width="611" llx="65" lly="0" urx="546" ury="546"/>
<char name="nine" width="556" llx="30" lly="-19" urx="522" ury="710"/>
<char name="ntilde" width="611" llx="65" lly="0" urx="546" ury="737"/>
<char name="numbersign" width="556" llx="18" lly="0" urx="538" ury="698"/>
<char name="o" width="611" llx="34" lly="-14" urx="578" ury="546"/>
<char name="oacute" width="611" llx="34" lly="-14" urx="578" ury="750"/>
<char name="ocircumflex" width="611" llx="34" lly="-14" urx="578" ury="750"/>
<char name="odieresis" width="611" llx="34" lly="-14" urx="578" ury="729"/>
<char name="oe" width="944" llx="34" lly="-14" urx="912" ury="546"/>
<char name="ogonek" width="333" llx="71" lly="-228" urx="304" ury="0"/>
<char name="ograve" width="611" llx="34" lly="-14" urx="578" ury="750"/>
<char name="one" width="556" llx="69" lly="0" urx="378" ury="710"/>
<char name="onehalf" width="834" llx="26" lly="-19" urx="794" ury="710"/>
<char name="onequarter" width="834" llx="26" lly="-19" urx="766" ury="710"/>
<char name="onesuperior" width="333" llx="26" lly="283" urx="237" ury="710"/>
<char name="ordfeminine" width="370" llx="22" lly="401" urx="347" ury="737"/>
<char name="ordmasculine" width="365" llx="6" lly="401" urx="360" ury="737"/>
<char name="oslash" width="611" llx="22" lly="-29" urx="589" ury="560"/>
<char name="otilde" width="611" llx="34" lly="-14" urx="578" ury="737"/>
<char name="p" width="611" llx="62" lly="-207" urx="578" ury="546"/>
<char name="paragraph" width="556" llx="-8" lly="-191" urx="539" ury="700"/>
<char name="parenleft" width="333" llx="35" lly="-208" urx="314" ury="734"/>
<char name="parenright" width="333" llx="19" lly="-208" urx="298" ury="734"/>
<char name="percent" width="889" llx="28" lly="-19" urx="861" ury="710"/>
<char name="period" width="278" llx="64" lly="0" urx="214" ury="146"/>
<char name="periodcentered" width="278" llx="58" lly="172" urx="220" ury="334"/>
<char name="perthousand" width="1000" llx="-3" lly="-19" urx="1003" ury="710"/>
<char name="plus" width="584" llx="40" lly="0" urx="544" ury="506"/>
<char name="plusminus" width="584" llx="40" lly="0" urx="544" ury="506"/>
<char name="q" width="611" llx="34" lly="-207" urx="552" ury="546"/>
<char name="question" width="611" llx="60" lly="0" urx="556" ury="727"/>
<char name="questiondown" width="611" llx="55" lly="-195" urx="551" ury="532"/>
<char name="quotedbl" width="474" llx="98" lly="447" urx="376" ury="718"/>
<char name="quotedblbase" width="500" llx="64" lly="-146" urx="436" ury="127"/>
<char name="quotedblleft" width="500" llx="64" lly="454" urx="436" ury="727"/>
<char name="quotedblright" width="500" llx="64" lly="445" urx="436" ury="718"/>
<char name="quoteleft" width="278" llx="69" lly="454" urx="209" ury="727"/>
<char name="quoteright" width="278" llx="69" lly="445" urx="209" ury="718"/>
<char name="quotesinglbase" width="278" llx="69" lly="-146" urx="209" ury="127"/>
<char name="quotesingle" width="238" llx="70" lly="447" urx="168" ury="718"/>
<char name="r" width="389" llx="64" lly="0" urx="373" ury="546"/>
<char name="registered" width="737" llx="-11" lly="-19" urx="748" ury="737"/>
<char name="ring" width="333" llx="59" lly="568" urx="275" ury="776"/>
<char name="s" width="556" llx="30" lly="-14" urx="519" ury="546"/>
<char name="scaron" width="556" llx="30" lly="-14" urx="519" ury="750"/>
<char name="section" width="556" llx="34" lly="-184" urx="522" ury="727"/>
<char name="semicolon" width="333" llx="92" lly="-168" urx="242" ury="512"/>
<char name="seven" width="556" llx="25" lly="0" urx="528" ury="698"/>
<char name="six" width="556" llx="31" lly="-19" urx="520" ury="710"/>
<char name="slash" width="278" llx="-33" lly="-19" urx="311" ury="737"/>
<char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="278"/>
<char name="sterling" width="556"/>
<char name="t" width="333"/>
<char name="thorn" width="611"/>
<char name="three" width="556"/>
<char name="threequarters" width="834"/>
<char name="threesuperior" width="333"/>
<char name="tilde" width="333"/>
<char name="trademark" width="1000"/>
<char name="two" width="556"/>
<char name="twosuperior" width="333"/>
<char name="u" width="611"/>
<char name="uacute" width="611"/>
<char name="ucircumflex" width="611"/>
<char name="udieresis" width="611"/>
<char name="ugrave" width="611"/>
<char name="underscore" width="556"/>
<char name="v" width="556"/>
<char name="w" width="778"/>
<char name="x" width="556"/>
<char name="y" width="556"/>
<char name="yacute" width="556"/>
<char name="ydieresis" width="556"/>
<char name="yen" width="556"/>
<char name="z" width="500"/>
<char name="zcaron" width="500"/>
<char name="zero" width="556"/>
</widths>
<char name="sterling" width="556" llx="28" lly="-16" urx="541" ury="718"/>
<char name="t" width="333" llx="10" lly="-6" urx="309" ury="676"/>
<char name="thorn" width="611" llx="62" lly="-208" urx="578" ury="718"/>
<char name="three" width="556" llx="27" lly="-19" urx="516" ury="710"/>
<char name="threequarters" width="834" llx="16" lly="-19" urx="799" ury="710"/>
<char name="threesuperior" width="333" llx="8" lly="271" urx="326" ury="710"/>
<char name="tilde" width="333" llx="-17" lly="610" urx="350" ury="737"/>
<char name="trademark" width="1000" llx="44" lly="306" urx="956" ury="718"/>
<char name="two" width="556" llx="26" lly="0" urx="511" ury="710"/>
<char name="twosuperior" width="333" llx="9" lly="283" urx="324" ury="710"/>
<char name="u" width="611" llx="66" lly="-14" urx="545" ury="532"/>
<char name="uacute" width="611" llx="66" lly="-14" urx="545" ury="750"/>
<char name="ucircumflex" width="611" llx="66" lly="-14" urx="545" ury="750"/>
<char name="udieresis" width="611" llx="66" lly="-14" urx="545" ury="729"/>
<char name="ugrave" width="611" llx="66" lly="-14" urx="545" ury="750"/>
<char name="underscore" width="556" llx="0" lly="-125" urx="556" ury="-75"/>
<char name="v" width="556" llx="13" lly="0" urx="543" ury="532"/>
<char name="w" width="778" llx="10" lly="0" urx="769" ury="532"/>
<char name="x" width="556" llx="15" lly="0" urx="541" ury="532"/>
<char name="y" width="556" llx="10" lly="-214" urx="539" ury="532"/>
<char name="yacute" width="556" llx="10" lly="-214" urx="539" ury="750"/>
<char name="ydieresis" width="556" llx="10" lly="-214" urx="539" ury="729"/>
<char name="yen" width="556" llx="-9" lly="0" urx="565" ury="698"/>
<char name="z" width="500" llx="20" lly="0" urx="480" ury="532"/>
<char name="zcaron" width="500" llx="20" lly="0" urx="480" ury="750"/>
<char name="zero" width="556" llx="32" lly="-19" urx="524" ury="710"/>
</char-metrics>
<kerning kpx1="107">
<pair kern="-15" kpx2="111"/>
</kerning>

+ 233
- 232
src/codegen/fonts/HelveticaBoldOblique.xml View File

@@ -22,245 +22,246 @@
<family-name>Helvetica</family-name>
<class-name>HelveticaBoldOblique</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>718</cap-height>
<x-height>532</x-height>
<ascender>718</ascender>
<descender>-207</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="722"/>
<char name="AE" width="1000"/>
<char name="Aacute" width="722"/>
<char name="Acircumflex" width="722"/>
<char name="Adieresis" width="722"/>
<char name="Agrave" width="722"/>
<char name="Aring" width="722"/>
<char name="Atilde" width="722"/>
<char name="B" width="722"/>
<char name="C" width="722"/>
<char name="Ccedilla" width="722"/>
<char name="D" width="722"/>
<char name="E" width="667"/>
<char name="Eacute" width="667"/>
<char name="Ecircumflex" width="667"/>
<char name="Edieresis" width="667"/>
<char name="Egrave" width="667"/>
<char name="Eth" width="722"/>
<char name="Euro" width="556"/>
<char name="F" width="611"/>
<char name="G" width="778"/>
<char name="H" width="722"/>
<char name="I" width="278"/>
<char name="Iacute" width="278"/>
<char name="Icircumflex" width="278"/>
<char name="Idieresis" width="278"/>
<char name="Igrave" width="278"/>
<char name="J" width="556"/>
<char name="K" width="722"/>
<char name="L" width="611"/>
<char name="Lslash" width="611"/>
<char name="M" width="833"/>
<char name="N" width="722"/>
<char name="Ntilde" width="722"/>
<char name="O" width="778"/>
<char name="OE" width="1000"/>
<char name="Oacute" width="778"/>
<char name="Ocircumflex" width="778"/>
<char name="Odieresis" width="778"/>
<char name="Ograve" width="778"/>
<char name="Oslash" width="778"/>
<char name="Otilde" width="778"/>
<char name="P" width="667"/>
<char name="Q" width="778"/>
<char name="R" width="722"/>
<char name="S" width="667"/>
<char name="Scaron" width="667"/>
<char name="T" width="611"/>
<char name="Thorn" width="667"/>
<char name="U" width="722"/>
<char name="Uacute" width="722"/>
<char name="Ucircumflex" width="722"/>
<char name="Udieresis" width="722"/>
<char name="Ugrave" width="722"/>
<char name="V" width="667"/>
<char name="W" width="944"/>
<char name="X" width="667"/>
<char name="Y" width="667"/>
<char name="Yacute" width="667"/>
<char name="Ydieresis" width="667"/>
<char name="Z" width="611"/>
<char name="Zcaron" width="611"/>
<char name="a" width="556"/>
<char name="aacute" width="556"/>
<char name="acircumflex" width="556"/>
<char name="acute" width="333"/>
<char name="adieresis" width="556"/>
<char name="ae" width="889"/>
<char name="agrave" width="556"/>
<char name="ampersand" width="722"/>
<char name="aring" width="556"/>
<char name="asciicircum" width="584"/>
<char name="asciitilde" width="584"/>
<char name="asterisk" width="389"/>
<char name="at" width="975"/>
<char name="atilde" width="556"/>
<char name="b" width="611"/>
<char name="backslash" width="278"/>
<char name="bar" width="280"/>
<char name="braceleft" width="389"/>
<char name="braceright" width="389"/>
<char name="bracketleft" width="333"/>
<char name="bracketright" width="333"/>
<char name="breve" width="333"/>
<char name="brokenbar" width="280"/>
<char name="bullet" width="350"/>
<char name="c" width="556"/>
<char name="caron" width="333"/>
<char name="ccedilla" width="556"/>
<char name="cedilla" width="333"/>
<char name="cent" width="556"/>
<char name="circumflex" width="333"/>
<char name="colon" width="333"/>
<char name="comma" width="278"/>
<char name="copyright" width="737"/>
<char name="currency" width="556"/>
<char name="d" width="611"/>
<char name="dagger" width="556"/>
<char name="daggerdbl" width="556"/>
<char name="degree" width="400"/>
<char name="dieresis" width="333"/>
<char name="divide" width="584"/>
<char name="dollar" width="556"/>
<char name="dotaccent" width="333"/>
<char name="dotlessi" width="278"/>
<char name="e" width="556"/>
<char name="eacute" width="556"/>
<char name="ecircumflex" width="556"/>
<char name="edieresis" width="556"/>
<char name="egrave" width="556"/>
<char name="eight" width="556"/>
<char name="ellipsis" width="1000"/>
<char name="emdash" width="1000"/>
<char name="endash" width="556"/>
<char name="equal" width="584"/>
<char name="eth" width="611"/>
<char name="exclam" width="333"/>
<char name="exclamdown" width="333"/>
<char name="f" width="333"/>
<char name="fi" width="611"/>
<char name="five" width="556"/>
<char name="fl" width="611"/>
<char name="florin" width="556"/>
<char name="four" width="556"/>
<char name="fraction" width="167"/>
<char name="g" width="611"/>
<char name="germandbls" width="611"/>
<char name="grave" width="333"/>
<char name="greater" width="584"/>
<char name="guillemotleft" width="556"/>
<char name="guillemotright" width="556"/>
<char name="guilsinglleft" width="333"/>
<char name="guilsinglright" width="333"/>
<char name="h" width="611"/>
<char name="hungarumlaut" width="333"/>
<char name="hyphen" width="333"/>
<char name="i" width="278"/>
<char name="iacute" width="278"/>
<char name="icircumflex" width="278"/>
<char name="idieresis" width="278"/>
<char name="igrave" width="278"/>
<char name="j" width="278"/>
<char name="k" width="556"/>
<char name="l" width="278"/>
<char name="less" width="584"/>
<char name="logicalnot" width="584"/>
<char name="lslash" width="278"/>
<char name="m" width="889"/>
<char name="macron" width="333"/>
<char name="minus" width="324"/>
<char name="mu" width="611"/>
<char name="multiply" width="584"/>
<char name="n" width="611"/>
<char name="nine" width="556"/>
<char name="ntilde" width="611"/>
<char name="numbersign" width="556"/>
<char name="o" width="611"/>
<char name="oacute" width="611"/>
<char name="ocircumflex" width="611"/>
<char name="odieresis" width="611"/>
<char name="oe" width="944"/>
<char name="ogonek" width="333"/>
<char name="ograve" width="611"/>
<char name="one" width="556"/>
<char name="onehalf" width="834"/>
<char name="onequarter" width="834"/>
<char name="onesuperior" width="333"/>
<char name="ordfeminine" width="370"/>
<char name="ordmasculine" width="365"/>
<char name="oslash" width="611"/>
<char name="otilde" width="611"/>
<char name="p" width="611"/>
<char name="paragraph" width="556"/>
<char name="parenleft" width="333"/>
<char name="parenright" width="333"/>
<char name="percent" width="889"/>
<char name="period" width="278"/>
<char name="periodcentered" width="278"/>
<char name="perthousand" width="1000"/>
<char name="plus" width="584"/>
<char name="plusminus" width="584"/>
<char name="q" width="611"/>
<char name="question" width="611"/>
<char name="questiondown" width="611"/>
<char name="quotedbl" width="474"/>
<char name="quotedblbase" width="500"/>
<char name="quotedblleft" width="500"/>
<char name="quotedblright" width="500"/>
<char name="quoteleft" width="278"/>
<char name="quoteright" width="278"/>
<char name="quotesinglbase" width="278"/>
<char name="quotesingle" width="238"/>
<char name="r" width="389"/>
<char name="registered" width="737"/>
<char name="ring" width="333"/>
<char name="s" width="556"/>
<char name="scaron" width="556"/>
<char name="section" width="556"/>
<char name="semicolon" width="333"/>
<char name="seven" width="556"/>
<char name="six" width="556"/>
<char name="slash" width="278"/>
<char name="space" width="278"/>
<char-metrics>
<char name="A" width="722" llx="20" lly="0" urx="702" ury="718"/>
<char name="AE" width="1000" llx="5" lly="0" urx="1100" ury="718"/>
<char name="Aacute" width="722" llx="20" lly="0" urx="750" ury="936"/>
<char name="Acircumflex" width="722" llx="20" lly="0" urx="706" ury="936"/>
<char name="Adieresis" width="722" llx="20" lly="0" urx="716" ury="915"/>
<char name="Agrave" width="722" llx="20" lly="0" urx="702" ury="936"/>
<char name="Aring" width="722" llx="20" lly="0" urx="702" ury="962"/>
<char name="Atilde" width="722" llx="20" lly="0" urx="741" ury="923"/>
<char name="B" width="722" llx="76" lly="0" urx="764" ury="718"/>
<char name="C" width="722" llx="107" lly="-19" urx="789" ury="737"/>
<char name="Ccedilla" width="722" llx="107" lly="-228" urx="789" ury="737"/>
<char name="D" width="722" llx="76" lly="0" urx="777" ury="718"/>
<char name="E" width="667" llx="76" lly="0" urx="757" ury="718"/>
<char name="Eacute" width="667" llx="76" lly="0" urx="757" ury="936"/>
<char name="Ecircumflex" width="667" llx="76" lly="0" urx="757" ury="936"/>
<char name="Edieresis" width="667" llx="76" lly="0" urx="757" ury="915"/>
<char name="Egrave" width="667" llx="76" lly="0" urx="757" ury="936"/>
<char name="Eth" width="722" llx="62" lly="0" urx="777" ury="718"/>
<char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="611" llx="76" lly="0" urx="740" ury="718"/>
<char name="G" width="778" llx="108" lly="-19" urx="817" ury="737"/>
<char name="H" width="722" llx="71" lly="0" urx="804" ury="718"/>
<char name="I" width="278" llx="64" lly="0" urx="367" ury="718"/>
<char name="Iacute" width="278" llx="64" lly="0" urx="528" ury="936"/>
<char name="Icircumflex" width="278" llx="64" lly="0" urx="484" ury="936"/>
<char name="Idieresis" width="278" llx="64" lly="0" urx="494" ury="915"/>
<char name="Igrave" width="278" llx="64" lly="0" urx="367" ury="936"/>
<char name="J" width="556" llx="60" lly="-18" urx="637" ury="718"/>
<char name="K" width="722" llx="87" lly="0" urx="858" ury="718"/>
<char name="L" width="611" llx="76" lly="0" urx="611" ury="718"/>
<char name="Lslash" width="611" llx="34" lly="0" urx="611" ury="718"/>
<char name="M" width="833" llx="69" lly="0" urx="918" ury="718"/>
<char name="N" width="722" llx="69" lly="0" urx="807" ury="718"/>
<char name="Ntilde" width="722" llx="69" lly="0" urx="807" ury="923"/>
<char name="O" width="778" llx="107" lly="-19" urx="823" ury="737"/>
<char name="OE" width="1000" llx="99" lly="-19" urx="1114" ury="737"/>
<char name="Oacute" width="778" llx="107" lly="-19" urx="823" ury="936"/>
<char name="Ocircumflex" width="778" llx="107" lly="-19" urx="823" ury="936"/>
<char name="Odieresis" width="778" llx="107" lly="-19" urx="823" ury="915"/>
<char name="Ograve" width="778" llx="107" lly="-19" urx="823" ury="936"/>
<char name="Oslash" width="778" llx="35" lly="-27" urx="894" ury="745"/>
<char name="Otilde" width="778" llx="107" lly="-19" urx="823" ury="923"/>
<char name="P" width="667" llx="76" lly="0" urx="738" ury="718"/>
<char name="Q" width="778" llx="107" lly="-52" urx="823" ury="737"/>
<char name="R" width="722" llx="76" lly="0" urx="778" ury="718"/>
<char name="S" width="667" llx="81" lly="-19" urx="718" ury="737"/>
<char name="Scaron" width="667" llx="81" lly="-19" urx="718" ury="936"/>
<char name="T" width="611" llx="140" lly="0" urx="751" ury="718"/>
<char name="Thorn" width="667" llx="76" lly="0" urx="716" ury="718"/>
<char name="U" width="722" llx="116" lly="-19" urx="804" ury="718"/>
<char name="Uacute" width="722" llx="116" lly="-19" urx="804" ury="936"/>
<char name="Ucircumflex" width="722" llx="116" lly="-19" urx="804" ury="936"/>
<char name="Udieresis" width="722" llx="116" lly="-19" urx="804" ury="915"/>
<char name="Ugrave" width="722" llx="116" lly="-19" urx="804" ury="936"/>
<char name="V" width="667" llx="172" lly="0" urx="801" ury="718"/>
<char name="W" width="944" llx="169" lly="0" urx="1082" ury="718"/>
<char name="X" width="667" llx="14" lly="0" urx="791" ury="718"/>
<char name="Y" width="667" llx="168" lly="0" urx="806" ury="718"/>
<char name="Yacute" width="667" llx="168" lly="0" urx="806" ury="936"/>
<char name="Ydieresis" width="667" llx="168" lly="0" urx="806" ury="915"/>
<char name="Z" width="611" llx="25" lly="0" urx="737" ury="718"/>
<char name="Zcaron" width="611" llx="25" lly="0" urx="737" ury="936"/>
<char name="a" width="556" llx="55" lly="-14" urx="583" ury="546"/>
<char name="aacute" width="556" llx="55" lly="-14" urx="627" ury="750"/>
<char name="acircumflex" width="556" llx="55" lly="-14" urx="583" ury="750"/>
<char name="acute" width="333" llx="236" lly="604" urx="515" ury="750"/>
<char name="adieresis" width="556" llx="55" lly="-14" urx="594" ury="729"/>
<char name="ae" width="889" llx="56" lly="-14" urx="923" ury="546"/>
<char name="agrave" width="556" llx="55" lly="-14" urx="583" ury="750"/>
<char name="ampersand" width="722" llx="89" lly="-19" urx="732" ury="718"/>
<char name="aring" width="556" llx="55" lly="-14" urx="583" ury="776"/>
<char name="asciicircum" width="584" llx="131" lly="323" urx="591" ury="698"/>
<char name="asciitilde" width="584" llx="115" lly="163" urx="577" ury="343"/>
<char name="asterisk" width="389" llx="146" lly="387" urx="481" ury="718"/>
<char name="at" width="975" llx="186" lly="-19" urx="954" ury="737"/>
<char name="atilde" width="556" llx="55" lly="-14" urx="619" ury="737"/>
<char name="b" width="611" llx="61" lly="-14" urx="645" ury="718"/>
<char name="backslash" width="278" llx="124" lly="-19" urx="307" ury="737"/>
<char name="bar" width="280" llx="36" lly="-225" urx="361" ury="775"/>
<char name="braceleft" width="389" llx="94" lly="-196" urx="518" ury="722"/>
<char name="braceright" width="389" llx="-18" lly="-196" urx="407" ury="722"/>
<char name="bracketleft" width="333" llx="21" lly="-196" urx="462" ury="722"/>
<char name="bracketright" width="333" llx="-18" lly="-196" urx="423" ury="722"/>
<char name="breve" width="333" llx="156" lly="604" urx="494" ury="750"/>
<char name="brokenbar" width="280" llx="52" lly="-150" urx="345" ury="700"/>
<char name="bullet" width="350" llx="83" lly="194" urx="420" ury="524"/>
<char name="c" width="556" llx="79" lly="-14" urx="599" ury="546"/>
<char name="caron" width="333" llx="149" lly="604" urx="502" ury="750"/>
<char name="ccedilla" width="556" llx="79" lly="-228" urx="599" ury="546"/>
<char name="cedilla" width="333" llx="-37" lly="-228" urx="220" ury="0"/>
<char name="cent" width="556" llx="79" lly="-118" urx="599" ury="628"/>
<char name="circumflex" width="333" llx="118" lly="604" urx="471" ury="750"/>
<char name="colon" width="333" llx="92" lly="0" urx="351" ury="512"/>
<char name="comma" width="278" llx="28" lly="-168" urx="245" ury="146"/>
<char name="copyright" width="737" llx="56" lly="-19" urx="835" ury="737"/>
<char name="currency" width="556" llx="27" lly="76" urx="680" ury="636"/>
<char name="d" width="611" llx="82" lly="-14" urx="704" ury="718"/>
<char name="dagger" width="556" llx="118" lly="-171" urx="626" ury="718"/>
<char name="daggerdbl" width="556" llx="46" lly="-171" urx="628" ury="718"/>
<char name="degree" width="400" llx="175" lly="426" urx="467" ury="712"/>
<char name="dieresis" width="333" llx="137" lly="614" urx="482" ury="729"/>
<char name="divide" width="584" llx="82" lly="-42" urx="610" ury="548"/>
<char name="dollar" width="556" llx="67" lly="-115" urx="622" ury="775"/>
<char name="dotaccent" width="333" llx="235" lly="614" urx="385" ury="729"/>
<char name="dotlessi" width="278" llx="69" lly="0" urx="322" ury="532"/>
<char name="e" width="556" llx="70" lly="-14" urx="593" ury="546"/>
<char name="eacute" width="556" llx="70" lly="-14" urx="627" ury="750"/>
<char name="ecircumflex" width="556" llx="70" lly="-14" urx="593" ury="750"/>
<char name="edieresis" width="556" llx="70" lly="-14" urx="594" ury="729"/>
<char name="egrave" width="556" llx="70" lly="-14" urx="593" ury="750"/>
<char name="eight" width="556" llx="69" lly="-19" urx="616" ury="710"/>
<char name="ellipsis" width="1000" llx="92" lly="0" urx="939" ury="146"/>
<char name="emdash" width="1000" llx="48" lly="227" urx="1071" ury="333"/>
<char name="endash" width="556" llx="48" lly="227" urx="627" ury="333"/>
<char name="equal" width="584" llx="58" lly="87" urx="633" ury="419"/>
<char name="eth" width="611" llx="82" lly="-14" urx="670" ury="737"/>
<char name="exclam" width="333" llx="94" lly="0" urx="397" ury="718"/>
<char name="exclamdown" width="333" llx="50" lly="-186" urx="353" ury="532"/>
<char name="f" width="333" llx="87" lly="0" urx="469" ury="727"/>
<char name="fi" width="611" llx="87" lly="0" urx="696" ury="727"/>
<char name="five" width="556" llx="64" lly="-19" urx="636" ury="698"/>
<char name="fl" width="611" llx="87" lly="0" urx="695" ury="727"/>
<char name="florin" width="556" llx="-50" lly="-210" urx="669" ury="737"/>
<char name="four" width="556" llx="60" lly="0" urx="598" ury="710"/>
<char name="fraction" width="167" llx="-174" lly="-19" urx="487" ury="710"/>
<char name="g" width="611" llx="38" lly="-217" urx="666" ury="546"/>
<char name="germandbls" width="611" llx="69" lly="-14" urx="657" ury="731"/>
<char name="grave" width="333" llx="136" lly="604" urx="353" ury="750"/>
<char name="greater" width="584" llx="36" lly="-8" urx="609" ury="514"/>
<char name="guillemotleft" width="556" llx="135" lly="76" urx="571" ury="484"/>
<char name="guillemotright" width="556" llx="104" lly="76" urx="540" ury="484"/>
<char name="guilsinglleft" width="333" llx="130" lly="76" urx="353" ury="484"/>
<char name="guilsinglright" width="333" llx="99" lly="76" urx="322" ury="484"/>
<char name="h" width="611" llx="65" lly="0" urx="629" ury="718"/>
<char name="hungarumlaut" width="333" llx="137" lly="604" urx="645" ury="750"/>
<char name="hyphen" width="333" llx="73" lly="215" urx="379" ury="345"/>
<char name="i" width="278" llx="69" lly="0" urx="363" ury="725"/>
<char name="iacute" width="278" llx="69" lly="0" urx="488" ury="750"/>
<char name="icircumflex" width="278" llx="69" lly="0" urx="444" ury="750"/>
<char name="idieresis" width="278" llx="69" lly="0" urx="455" ury="729"/>
<char name="igrave" width="278" llx="69" lly="0" urx="326" ury="750"/>
<char name="j" width="278" llx="-42" lly="-214" urx="363" ury="725"/>
<char name="k" width="556" llx="69" lly="0" urx="670" ury="718"/>
<char name="l" width="278" llx="69" lly="0" urx="362" ury="718"/>
<char name="less" width="584" llx="82" lly="-8" urx="655" ury="514"/>
<char name="logicalnot" width="584" llx="105" lly="108" urx="633" ury="419"/>
<char name="lslash" width="278" llx="40" lly="0" urx="407" ury="718"/>
<char name="m" width="889" llx="64" lly="0" urx="909" ury="546"/>
<char name="macron" width="333" llx="122" lly="604" urx="483" ury="678"/>
<char name="minus" width="324" llx="82" lly="197" urx="610" ury="309"/>
<char name="mu" width="611" llx="22" lly="-207" urx="658" ury="532"/>
<char name="multiply" width="584" llx="57" lly="1" urx="635" ury="505"/>
<char name="n" width="611" llx="65" lly="0" urx="629" ury="546"/>
<char name="nine" width="556" llx="78" lly="-19" urx="615" ury="710"/>
<char name="ntilde" width="611" llx="65" lly="0" urx="646" ury="737"/>
<char name="numbersign" width="556" llx="60" lly="0" urx="644" ury="698"/>
<char name="o" width="611" llx="82" lly="-14" urx="643" ury="546"/>
<char name="oacute" width="611" llx="82" lly="-14" urx="654" ury="750"/>
<char name="ocircumflex" width="611" llx="82" lly="-14" urx="643" ury="750"/>
<char name="odieresis" width="611" llx="82" lly="-14" urx="643" ury="729"/>
<char name="oe" width="944" llx="82" lly="-14" urx="977" ury="546"/>
<char name="ogonek" width="333" llx="41" lly="-228" urx="264" ury="0"/>
<char name="ograve" width="611" llx="82" lly="-14" urx="643" ury="750"/>
<char name="one" width="556" llx="173" lly="0" urx="529" ury="710"/>
<char name="onehalf" width="834" llx="132" lly="-19" urx="858" ury="710"/>
<char name="onequarter" width="834" llx="132" lly="-19" urx="806" ury="710"/>
<char name="onesuperior" width="333" llx="148" lly="283" urx="388" ury="710"/>
<char name="ordfeminine" width="370" llx="125" lly="401" urx="465" ury="737"/>
<char name="ordmasculine" width="365" llx="123" lly="401" urx="485" ury="737"/>
<char name="oslash" width="611" llx="22" lly="-29" urx="701" ury="560"/>
<char name="otilde" width="611" llx="82" lly="-14" urx="646" ury="737"/>
<char name="p" width="611" llx="18" lly="-207" urx="645" ury="546"/>
<char name="paragraph" width="556" llx="98" lly="-191" urx="688" ury="700"/>
<char name="parenleft" width="333" llx="76" lly="-208" urx="470" ury="734"/>
<char name="parenright" width="333" llx="-25" lly="-208" urx="369" ury="734"/>
<char name="percent" width="889" llx="136" lly="-19" urx="901" ury="710"/>
<char name="period" width="278" llx="64" lly="0" urx="245" ury="146"/>
<char name="periodcentered" width="278" llx="110" lly="172" urx="276" ury="334"/>
<char name="perthousand" width="1000" llx="76" lly="-19" urx="1038" ury="710"/>
<char name="plus" width="584" llx="82" lly="0" urx="610" ury="506"/>
<char name="plusminus" width="584" llx="40" lly="0" urx="625" ury="506"/>
<char name="q" width="611" llx="80" lly="-207" urx="665" ury="546"/>
<char name="question" width="611" llx="165" lly="0" urx="671" ury="727"/>
<char name="questiondown" width="611" llx="53" lly="-195" urx="559" ury="532"/>
<char name="quotedbl" width="474" llx="193" lly="447" urx="529" ury="718"/>
<char name="quotedblbase" width="500" llx="36" lly="-146" urx="463" ury="127"/>
<char name="quotedblleft" width="500" llx="160" lly="454" urx="588" ury="727"/>
<char name="quotedblright" width="500" llx="162" lly="445" urx="589" ury="718"/>
<char name="quoteleft" width="278" llx="165" lly="454" urx="361" ury="727"/>
<char name="quoteright" width="278" llx="167" lly="445" urx="362" ury="718"/>
<char name="quotesinglbase" width="278" llx="41" lly="-146" urx="236" ury="127"/>
<char name="quotesingle" width="238" llx="165" lly="447" urx="321" ury="718"/>
<char name="r" width="389" llx="64" lly="0" urx="489" ury="546"/>
<char name="registered" width="737" llx="55" lly="-19" urx="834" ury="737"/>
<char name="ring" width="333" llx="200" lly="568" urx="420" ury="776"/>
<char name="s" width="556" llx="63" lly="-14" urx="584" ury="546"/>
<char name="scaron" width="556" llx="63" lly="-14" urx="614" ury="750"/>
<char name="section" width="556" llx="61" lly="-184" urx="598" ury="727"/>
<char name="semicolon" width="333" llx="56" lly="-168" urx="351" ury="512"/>
<char name="seven" width="556" llx="125" lly="0" urx="676" ury="698"/>
<char name="six" width="556" llx="85" lly="-19" urx="619" ury="710"/>
<char name="slash" width="278" llx="-37" lly="-19" urx="468" ury="737"/>
<char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="278"/>
<char name="sterling" width="556"/>
<char name="t" width="333"/>
<char name="thorn" width="611"/>
<char name="three" width="556"/>
<char name="threequarters" width="834"/>
<char name="threesuperior" width="333"/>
<char name="tilde" width="333"/>
<char name="trademark" width="1000"/>
<char name="two" width="556"/>
<char name="twosuperior" width="333"/>
<char name="u" width="611"/>
<char name="uacute" width="611"/>
<char name="ucircumflex" width="611"/>
<char name="udieresis" width="611"/>
<char name="ugrave" width="611"/>
<char name="underscore" width="556"/>
<char name="v" width="556"/>
<char name="w" width="778"/>
<char name="x" width="556"/>
<char name="y" width="556"/>
<char name="yacute" width="556"/>
<char name="ydieresis" width="556"/>
<char name="yen" width="556"/>
<char name="z" width="500"/>
<char name="zcaron" width="500"/>
<char name="zero" width="556"/>
</widths>
<char name="sterling" width="556" llx="50" lly="-16" urx="635" ury="718"/>
<char name="t" width="333" llx="100" lly="-6" urx="422" ury="676"/>
<char name="thorn" width="611" llx="18" lly="-208" urx="645" ury="718"/>
<char name="three" width="556" llx="65" lly="-19" urx="608" ury="710"/>
<char name="threequarters" width="834" llx="99" lly="-19" urx="839" ury="710"/>
<char name="threesuperior" width="333" llx="91" lly="271" urx="441" ury="710"/>
<char name="tilde" width="333" llx="113" lly="610" urx="507" ury="737"/>
<char name="trademark" width="1000" llx="179" lly="306" urx="1109" ury="718"/>
<char name="two" width="556" llx="26" lly="0" urx="619" ury="710"/>
<char name="twosuperior" width="333" llx="69" lly="283" urx="449" ury="710"/>
<char name="u" width="611" llx="98" lly="-14" urx="658" ury="532"/>
<char name="uacute" width="611" llx="98" lly="-14" urx="658" ury="750"/>
<char name="ucircumflex" width="611" llx="98" lly="-14" urx="658" ury="750"/>
<char name="udieresis" width="611" llx="98" lly="-14" urx="658" ury="729"/>
<char name="ugrave" width="611" llx="98" lly="-14" urx="658" ury="750"/>
<char name="underscore" width="556" llx="-27" lly="-125" urx="540" ury="-75"/>
<char name="v" width="556" llx="126" lly="0" urx="656" ury="532"/>
<char name="w" width="778" llx="123" lly="0" urx="882" ury="532"/>
<char name="x" width="556" llx="15" lly="0" urx="648" ury="532"/>
<char name="y" width="556" llx="42" lly="-214" urx="652" ury="532"/>
<char name="yacute" width="556" llx="42" lly="-214" urx="652" ury="750"/>
<char name="ydieresis" width="556" llx="42" lly="-214" urx="652" ury="729"/>
<char name="yen" width="556" llx="60" lly="0" urx="713" ury="698"/>
<char name="z" width="500" llx="20" lly="0" urx="583" ury="532"/>
<char name="zcaron" width="500" llx="20" lly="0" urx="586" ury="750"/>
<char name="zero" width="556" llx="86" lly="-19" urx="617" ury="710"/>
</char-metrics>
<kerning kpx1="107">
<pair kern="-15" kpx2="111"/>
</kerning>

+ 234
- 233
src/codegen/fonts/HelveticaOblique.xml View File

@@ -22,245 +22,246 @@
<family-name>Helvetica</family-name>
<class-name>HelveticaOblique</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>718</cap-height>
<x-height>523</x-height>
<ascender>718</ascender>
<descender>-207</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="667"/>
<char name="AE" width="1000"/>
<char name="Aacute" width="667"/>
<char name="Acircumflex" width="667"/>
<char name="Adieresis" width="667"/>
<char name="Agrave" width="667"/>
<char name="Aring" width="667"/>
<char name="Atilde" width="667"/>
<char name="B" width="667"/>
<char name="C" width="722"/>
<char name="Ccedilla" width="722"/>
<char name="D" width="722"/>
<char name="E" width="667"/>
<char name="Eacute" width="667"/>
<char name="Ecircumflex" width="667"/>
<char name="Edieresis" width="667"/>
<char name="Egrave" width="667"/>
<char name="Eth" width="722"/>
<char name="Euro" width="556"/>
<char name="F" width="611"/>
<char name="G" width="778"/>
<char name="H" width="722"/>
<char name="I" width="278"/>
<char name="Iacute" width="278"/>
<char name="Icircumflex" width="278"/>
<char name="Idieresis" width="278"/>
<char name="Igrave" width="278"/>
<char name="J" width="500"/>
<char name="K" width="667"/>
<char name="L" width="556"/>
<char name="Lslash" width="556"/>
<char name="M" width="833"/>
<char name="N" width="722"/>
<char name="Ntilde" width="722"/>
<char name="O" width="778"/>
<char name="OE" width="1000"/>
<char name="Oacute" width="778"/>
<char name="Ocircumflex" width="778"/>
<char name="Odieresis" width="778"/>
<char name="Ograve" width="778"/>
<char name="Oslash" width="778"/>
<char name="Otilde" width="778"/>
<char name="P" width="667"/>
<char name="Q" width="778"/>
<char name="R" width="722"/>
<char name="S" width="667"/>
<char name="Scaron" width="667"/>
<char name="T" width="611"/>
<char name="Thorn" width="667"/>
<char name="U" width="722"/>
<char name="Uacute" width="722"/>
<char name="Ucircumflex" width="722"/>
<char name="Udieresis" width="722"/>
<char name="Ugrave" width="722"/>
<char name="V" width="667"/>
<char name="W" width="944"/>
<char name="X" width="667"/>
<char name="Y" width="667"/>
<char name="Yacute" width="667"/>
<char name="Ydieresis" width="667"/>
<char name="Z" width="611"/>
<char name="Zcaron" width="611"/>
<char name="a" width="556"/>
<char name="aacute" width="556"/>
<char name="acircumflex" width="556"/>
<char name="acute" width="333"/>
<char name="adieresis" width="556"/>
<char name="ae" width="889"/>
<char name="agrave" width="556"/>
<char name="ampersand" width="667"/>
<char name="aring" width="556"/>
<char name="asciicircum" width="469"/>
<char name="asciitilde" width="584"/>
<char name="asterisk" width="389"/>
<char name="at" width="1015"/>
<char name="atilde" width="556"/>
<char name="b" width="556"/>
<char name="backslash" width="278"/>
<char name="bar" width="260"/>
<char name="braceleft" width="334"/>
<char name="braceright" width="334"/>
<char name="bracketleft" width="278"/>
<char name="bracketright" width="278"/>
<char name="breve" width="333"/>
<char name="brokenbar" width="260"/>
<char name="bullet" width="350"/>
<char name="c" width="500"/>
<char name="caron" width="333"/>
<char name="ccedilla" width="500"/>
<char name="cedilla" width="333"/>
<char name="cent" width="556"/>
<char name="circumflex" width="333"/>
<char name="colon" width="278"/>
<char name="comma" width="278"/>
<char name="copyright" width="737"/>
<char name="currency" width="556"/>
<char name="d" width="556"/>
<char name="dagger" width="556"/>
<char name="daggerdbl" width="556"/>
<char name="degree" width="400"/>
<char name="dieresis" width="333"/>
<char name="divide" width="584"/>
<char name="dollar" width="556"/>
<char name="dotaccent" width="333"/>
<char name="dotlessi" width="278"/>
<char name="e" width="556"/>
<char name="eacute" width="556"/>
<char name="ecircumflex" width="556"/>
<char name="edieresis" width="556"/>
<char name="egrave" width="556"/>
<char name="eight" width="556"/>
<char name="ellipsis" width="1000"/>
<char name="emdash" width="1000"/>
<char name="endash" width="556"/>
<char name="equal" width="584"/>
<char name="eth" width="556"/>
<char name="exclam" width="278"/>
<char name="exclamdown" width="333"/>
<char name="f" width="278"/>
<char name="fi" width="500"/>
<char name="five" width="556"/>
<char name="fl" width="500"/>
<char name="florin" width="556"/>
<char name="four" width="556"/>
<char name="fraction" width="167"/>
<char name="g" width="556"/>
<char name="germandbls" width="611"/>
<char name="grave" width="333"/>
<char name="greater" width="584"/>
<char name="guillemotleft" width="556"/>
<char name="guillemotright" width="556"/>
<char name="guilsinglleft" width="333"/>
<char name="guilsinglright" width="333"/>
<char name="h" width="556"/>
<char name="hungarumlaut" width="333"/>
<char name="hyphen" width="333"/>
<char name="i" width="222"/>
<char name="iacute" width="278"/>
<char name="icircumflex" width="278"/>
<char name="idieresis" width="278"/>
<char name="igrave" width="278"/>
<char name="j" width="222"/>
<char name="k" width="500"/>
<char name="l" width="222"/>
<char name="less" width="584"/>
<char name="logicalnot" width="584"/>
<char name="lslash" width="222"/>
<char name="m" width="833"/>
<char name="macron" width="333"/>
<char name="minus" width="584"/>
<char name="mu" width="556"/>
<char name="multiply" width="584"/>
<char name="n" width="556"/>
<char name="nine" width="556"/>
<char name="ntilde" width="556"/>
<char name="numbersign" width="556"/>
<char name="o" width="556"/>
<char name="oacute" width="556"/>
<char name="ocircumflex" width="556"/>
<char name="odieresis" width="556"/>
<char name="oe" width="944"/>
<char name="ogonek" width="333"/>
<char name="ograve" width="556"/>
<char name="one" width="556"/>
<char name="onehalf" width="834"/>
<char name="onequarter" width="834"/>
<char name="onesuperior" width="333"/>
<char name="ordfeminine" width="370"/>
<char name="ordmasculine" width="365"/>
<char name="oslash" width="611"/>
<char name="otilde" width="556"/>
<char name="p" width="556"/>
<char name="paragraph" width="537"/>
<char name="parenleft" width="333"/>
<char name="parenright" width="333"/>
<char name="percent" width="889"/>
<char name="period" width="278"/>
<char name="periodcentered" width="278"/>
<char name="perthousand" width="1000"/>
<char name="plus" width="584"/>
<char name="plusminus" width="584"/>
<char name="q" width="556"/>
<char name="question" width="556"/>
<char name="questiondown" width="611"/>
<char name="quotedbl" width="355"/>
<char name="quotedblbase" width="333"/>
<char name="quotedblleft" width="333"/>
<char name="quotedblright" width="333"/>
<char name="quoteleft" width="222"/>
<char name="quoteright" width="222"/>
<char name="quotesinglbase" width="222"/>
<char name="quotesingle" width="191"/>
<char name="r" width="333"/>
<char name="registered" width="737"/>
<char name="ring" width="333"/>
<char name="s" width="500"/>
<char name="scaron" width="500"/>
<char name="section" width="556"/>
<char name="semicolon" width="278"/>
<char name="seven" width="556"/>
<char name="six" width="556"/>
<char name="slash" width="278"/>
<char name="space" width="278"/>
<char-metrics>
<char name="A" width="667" llx="14" lly="0" urx="654" ury="718"/>
<char name="AE" width="1000" llx="8" lly="0" urx="1097" ury="718"/>
<char name="Aacute" width="667" llx="14" lly="0" urx="683" ury="929"/>
<char name="Acircumflex" width="667" llx="14" lly="0" urx="654" ury="929"/>
<char name="Adieresis" width="667" llx="14" lly="0" urx="654" ury="901"/>
<char name="Agrave" width="667" llx="14" lly="0" urx="654" ury="929"/>
<char name="Aring" width="667" llx="14" lly="0" urx="654" ury="931"/>
<char name="Atilde" width="667" llx="14" lly="0" urx="699" ury="917"/>
<char name="B" width="667" llx="74" lly="0" urx="712" ury="718"/>
<char name="C" width="722" llx="108" lly="-19" urx="782" ury="737"/>
<char name="Ccedilla" width="722" llx="108" lly="-225" urx="782" ury="737"/>
<char name="D" width="722" llx="81" lly="0" urx="764" ury="718"/>
<char name="E" width="667" llx="86" lly="0" urx="762" ury="718"/>
<char name="Eacute" width="667" llx="86" lly="0" urx="762" ury="929"/>
<char name="Ecircumflex" width="667" llx="86" lly="0" urx="762" ury="929"/>
<char name="Edieresis" width="667" llx="86" lly="0" urx="762" ury="901"/>
<char name="Egrave" width="667" llx="86" lly="0" urx="762" ury="929"/>
<char name="Eth" width="722" llx="69" lly="0" urx="764" ury="718"/>
<char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="611" llx="86" lly="0" urx="736" ury="718"/>
<char name="G" width="778" llx="111" lly="-19" urx="799" ury="737"/>
<char name="H" width="722" llx="77" lly="0" urx="799" ury="718"/>
<char name="I" width="278" llx="91" lly="0" urx="341" ury="718"/>
<char name="Iacute" width="278" llx="91" lly="0" urx="489" ury="929"/>
<char name="Icircumflex" width="278" llx="91" lly="0" urx="452" ury="929"/>
<char name="Idieresis" width="278" llx="91" lly="0" urx="458" ury="901"/>
<char name="Igrave" width="278" llx="91" lly="0" urx="351" ury="929"/>
<char name="J" width="500" llx="47" lly="-19" urx="581" ury="718"/>
<char name="K" width="667" llx="76" lly="0" urx="808" ury="718"/>
<char name="L" width="556" llx="76" lly="0" urx="555" ury="718"/>
<char name="Lslash" width="556" llx="41" lly="0" urx="555" ury="718"/>
<char name="M" width="833" llx="73" lly="0" urx="914" ury="718"/>
<char name="N" width="722" llx="76" lly="0" urx="799" ury="718"/>
<char name="Ntilde" width="722" llx="76" lly="0" urx="799" ury="917"/>
<char name="O" width="778" llx="105" lly="-19" urx="826" ury="737"/>
<char name="OE" width="1000" llx="98" lly="-19" urx="1116" ury="737"/>
<char name="Oacute" width="778" llx="105" lly="-19" urx="826" ury="929"/>
<char name="Ocircumflex" width="778" llx="105" lly="-19" urx="826" ury="929"/>
<char name="Odieresis" width="778" llx="105" lly="-19" urx="826" ury="901"/>
<char name="Ograve" width="778" llx="105" lly="-19" urx="826" ury="929"/>
<char name="Oslash" width="778" llx="43" lly="-19" urx="890" ury="737"/>
<char name="Otilde" width="778" llx="105" lly="-19" urx="826" ury="917"/>
<char name="P" width="667" llx="86" lly="0" urx="737" ury="718"/>
<char name="Q" width="778" llx="105" lly="-56" urx="826" ury="737"/>
<char name="R" width="722" llx="88" lly="0" urx="773" ury="718"/>
<char name="S" width="667" llx="90" lly="-19" urx="713" ury="737"/>
<char name="Scaron" width="667" llx="90" lly="-19" urx="713" ury="929"/>
<char name="T" width="611" llx="148" lly="0" urx="750" ury="718"/>
<char name="Thorn" width="667" llx="86" lly="0" urx="712" ury="718"/>
<char name="U" width="722" llx="123" lly="-19" urx="797" ury="718"/>
<char name="Uacute" width="722" llx="123" lly="-19" urx="797" ury="929"/>
<char name="Ucircumflex" width="722" llx="123" lly="-19" urx="797" ury="929"/>
<char name="Udieresis" width="722" llx="123" lly="-19" urx="797" ury="901"/>
<char name="Ugrave" width="722" llx="123" lly="-19" urx="797" ury="929"/>
<char name="V" width="667" llx="173" lly="0" urx="800" ury="718"/>
<char name="W" width="944" llx="169" lly="0" urx="1081" ury="718"/>
<char name="X" width="667" llx="19" lly="0" urx="790" ury="718"/>
<char name="Y" width="667" llx="167" lly="0" urx="806" ury="718"/>
<char name="Yacute" width="667" llx="167" lly="0" urx="806" ury="929"/>
<char name="Ydieresis" width="667" llx="167" lly="0" urx="806" ury="901"/>
<char name="Z" width="611" llx="23" lly="0" urx="741" ury="718"/>
<char name="Zcaron" width="611" llx="23" lly="0" urx="741" ury="929"/>
<char name="a" width="556" llx="61" lly="-15" urx="559" ury="538"/>
<char name="aacute" width="556" llx="61" lly="-15" urx="587" ury="734"/>
<char name="acircumflex" width="556" llx="61" lly="-15" urx="559" ury="734"/>
<char name="acute" width="333" llx="248" lly="593" urx="475" ury="734"/>
<char name="adieresis" width="556" llx="61" lly="-15" urx="559" ury="706"/>
<char name="ae" width="889" llx="61" lly="-15" urx="909" ury="538"/>
<char name="agrave" width="556" llx="61" lly="-15" urx="559" ury="734"/>
<char name="ampersand" width="667" llx="77" lly="-15" urx="647" ury="718"/>
<char name="aring" width="556" llx="61" lly="-15" urx="559" ury="756"/>
<char name="asciicircum" width="469" llx="42" lly="264" urx="539" ury="688"/>
<char name="asciitilde" width="584" llx="111" lly="180" urx="580" ury="326"/>
<char name="asterisk" width="389" llx="165" lly="431" urx="475" ury="718"/>
<char name="at" width="1015" llx="215" lly="-19" urx="965" ury="737"/>
<char name="atilde" width="556" llx="61" lly="-15" urx="592" ury="722"/>
<char name="b" width="556" llx="58" lly="-15" urx="584" ury="718"/>
<char name="backslash" width="278" llx="140" lly="-19" urx="291" ury="737"/>
<char name="bar" width="260" llx="46" lly="-225" urx="332" ury="775"/>
<char name="braceleft" width="334" llx="92" lly="-196" urx="445" ury="722"/>
<char name="braceright" width="334" llx="0" lly="-196" urx="354" ury="722"/>
<char name="bracketleft" width="278" llx="21" lly="-196" urx="403" ury="722"/>
<char name="bracketright" width="278" llx="-14" lly="-196" urx="368" ury="722"/>
<char name="breve" width="333" llx="167" lly="595" urx="476" ury="731"/>
<char name="brokenbar" width="260" llx="62" lly="-150" urx="316" ury="700"/>
<char name="bullet" width="350" llx="91" lly="202" urx="413" ury="517"/>
<char name="c" width="500" llx="74" lly="-15" urx="553" ury="538"/>
<char name="caron" width="333" llx="177" lly="593" urx="468" ury="734"/>
<char name="ccedilla" width="500" llx="74" lly="-225" urx="553" ury="538"/>
<char name="cedilla" width="333" llx="2" lly="-225" urx="232" ury="0"/>
<char name="cent" width="556" llx="95" lly="-115" urx="584" ury="623"/>
<char name="circumflex" width="333" llx="147" lly="593" urx="438" ury="734"/>
<char name="colon" width="278" llx="87" lly="0" urx="301" ury="516"/>
<char name="comma" width="278" llx="56" lly="-147" urx="214" ury="106"/>
<char name="copyright" width="737" llx="54" lly="-19" urx="837" ury="737"/>
<char name="currency" width="556" llx="60" lly="99" urx="646" ury="603"/>
<char name="d" width="556" llx="84" lly="-15" urx="652" ury="718"/>
<char name="dagger" width="556" llx="135" lly="-159" urx="622" ury="718"/>
<char name="daggerdbl" width="556" llx="52" lly="-159" urx="623" ury="718"/>
<char name="degree" width="400" llx="169" lly="411" urx="468" ury="703"/>
<char name="dieresis" width="333" llx="168" lly="604" urx="443" ury="706"/>
<char name="divide" width="584" llx="85" lly="-19" urx="606" ury="524"/>
<char name="dollar" width="556" llx="69" lly="-115" urx="617" ury="775"/>
<char name="dotaccent" width="333" llx="249" lly="604" urx="362" ury="706"/>
<char name="dotlessi" width="278" llx="95" lly="0" urx="294" ury="523"/>
<char name="e" width="556" llx="84" lly="-15" urx="578" ury="538"/>
<char name="eacute" width="556" llx="84" lly="-15" urx="587" ury="734"/>
<char name="ecircumflex" width="556" llx="84" lly="-15" urx="578" ury="734"/>
<char name="edieresis" width="556" llx="84" lly="-15" urx="578" ury="706"/>
<char name="egrave" width="556" llx="84" lly="-15" urx="578" ury="734"/>
<char name="eight" width="556" llx="74" lly="-19" urx="607" ury="703"/>
<char name="ellipsis" width="1000" llx="115" lly="0" urx="908" ury="106"/>
<char name="emdash" width="1000" llx="51" lly="240" urx="1067" ury="313"/>
<char name="endash" width="556" llx="51" lly="240" urx="623" ury="313"/>
<char name="equal" width="584" llx="63" lly="115" urx="628" ury="390"/>
<char name="eth" width="556" llx="81" lly="-15" urx="617" ury="737"/>
<char name="exclam" width="278" llx="90" lly="0" urx="340" ury="718"/>
<char name="exclamdown" width="333" llx="77" lly="-195" urx="326" ury="523"/>
<char name="f" width="278" llx="86" lly="0" urx="416" ury="728"/>
<char name="fi" width="500" llx="86" lly="0" urx="587" ury="728"/>
<char name="five" width="556" llx="68" lly="-19" urx="621" ury="688"/>
<char name="fl" width="500" llx="86" lly="0" urx="585" ury="728"/>
<char name="florin" width="556" llx="-52" lly="-207" urx="654" ury="737"/>
<char name="four" width="556" llx="61" lly="0" urx="576" ury="703"/>
<char name="fraction" width="167" llx="-170" lly="-19" urx="482" ury="703"/>
<char name="g" width="556" llx="42" lly="-220" urx="610" ury="538"/>
<char name="germandbls" width="611" llx="67" lly="-15" urx="658" ury="728"/>
<char name="grave" width="333" llx="170" lly="593" urx="337" ury="734"/>
<char name="greater" width="584" llx="50" lly="11" urx="597" ury="495"/>
<char name="guillemotleft" width="556" llx="146" lly="108" urx="554" ury="446"/>
<char name="guillemotright" width="556" llx="120" lly="108" urx="528" ury="446"/>
<char name="guilsinglleft" width="333" llx="137" lly="108" urx="340" ury="446"/>
<char name="guilsinglright" width="333" llx="111" lly="108" urx="314" ury="446"/>
<char name="h" width="556" llx="65" lly="0" urx="573" ury="718"/>
<char name="hungarumlaut" width="333" llx="157" lly="593" urx="565" ury="734"/>
<char name="hyphen" width="333" llx="93" lly="232" urx="357" ury="322"/>
<char name="i" width="222" llx="67" lly="0" urx="308" ury="718"/>
<char name="iacute" width="278" llx="95" lly="0" urx="448" ury="734"/>
<char name="icircumflex" width="278" llx="95" lly="0" urx="411" ury="734"/>
<char name="idieresis" width="278" llx="95" lly="0" urx="416" ury="706"/>
<char name="igrave" width="278" llx="95" lly="0" urx="310" ury="734"/>
<char name="j" width="222" llx="-60" lly="-210" urx="308" ury="718"/>
<char name="k" width="500" llx="67" lly="0" urx="600" ury="718"/>
<char name="l" width="222" llx="67" lly="0" urx="308" ury="718"/>
<char name="less" width="584" llx="94" lly="11" urx="641" ury="495"/>
<char name="logicalnot" width="584" llx="106" lly="108" urx="628" ury="390"/>
<char name="lslash" width="222" llx="41" lly="0" urx="347" ury="718"/>
<char name="m" width="833" llx="65" lly="0" urx="852" ury="538"/>
<char name="macron" width="333" llx="143" lly="627" urx="468" ury="684"/>
<char name="minus" width="584" llx="85" lly="216" urx="606" ury="289"/>
<char name="mu" width="556" llx="24" lly="-207" urx="600" ury="523"/>
<char name="multiply" width="584" llx="50" lly="0" urx="642" ury="506"/>
<char name="n" width="556" llx="65" lly="0" urx="573" ury="538"/>
<char name="nine" width="556" llx="82" lly="-19" urx="609" ury="703"/>
<char name="ntilde" width="556" llx="65" lly="0" urx="592" ury="722"/>
<char name="numbersign" width="556" llx="73" lly="0" urx="631" ury="688"/>
<char name="o" width="556" llx="83" lly="-14" urx="585" ury="538"/>
<char name="oacute" width="556" llx="83" lly="-14" urx="587" ury="734"/>
<char name="ocircumflex" width="556" llx="83" lly="-14" urx="585" ury="734"/>
<char name="odieresis" width="556" llx="83" lly="-14" urx="585" ury="706"/>
<char name="oe" width="944" llx="83" lly="-15" urx="964" ury="538"/>
<char name="ogonek" width="333" llx="43" lly="-225" urx="249" ury="0"/>
<char name="ograve" width="556" llx="83" lly="-14" urx="585" ury="734"/>
<char name="one" width="556" llx="207" lly="0" urx="508" ury="703"/>
<char name="onehalf" width="834" llx="114" lly="-19" urx="839" ury="703"/>
<char name="onequarter" width="834" llx="150" lly="-19" urx="802" ury="703"/>
<char name="onesuperior" width="333" llx="166" lly="281" urx="371" ury="703"/>
<char name="ordfeminine" width="370" llx="127" lly="405" urx="449" ury="737"/>
<char name="ordmasculine" width="365" llx="141" lly="405" urx="468" ury="737"/>
<char name="oslash" width="611" llx="29" lly="-22" urx="647" ury="545"/>
<char name="otilde" width="556" llx="83" lly="-14" urx="602" ury="722"/>
<char name="p" width="556" llx="14" lly="-207" urx="584" ury="538"/>
<char name="paragraph" width="537" llx="126" lly="-173" urx="650" ury="718"/>
<char name="parenleft" width="333" llx="108" lly="-207" urx="454" ury="733"/>
<char name="parenright" width="333" llx="-9" lly="-207" urx="337" ury="733"/>
<char name="percent" width="889" llx="147" lly="-19" urx="889" ury="703"/>
<char name="period" width="278" llx="87" lly="0" urx="214" ury="106"/>
<char name="periodcentered" width="278" llx="129" lly="190" urx="257" ury="315"/>
<char name="perthousand" width="1000" llx="88" lly="-19" urx="1029" ury="703"/>
<char name="plus" width="584" llx="85" lly="0" urx="606" ury="505"/>
<char name="plusminus" width="584" llx="39" lly="0" urx="618" ury="506"/>
<char name="q" width="556" llx="84" lly="-207" urx="605" ury="538"/>
<char name="question" width="556" llx="161" lly="0" urx="610" ury="727"/>
<char name="questiondown" width="611" llx="85" lly="-201" urx="534" ury="525"/>
<char name="quotedbl" width="355" llx="168" lly="463" urx="438" ury="718"/>
<char name="quotedblbase" width="333" llx="-6" lly="-149" urx="318" ury="106"/>
<char name="quotedblleft" width="333" llx="138" lly="470" urx="461" ury="725"/>
<char name="quotedblright" width="333" llx="124" lly="463" urx="448" ury="718"/>
<char name="quoteleft" width="222" llx="165" lly="470" urx="323" ury="725"/>
<char name="quoteright" width="222" llx="151" lly="463" urx="310" ury="718"/>
<char name="quotesinglbase" width="222" llx="21" lly="-149" urx="180" ury="106"/>
<char name="quotesingle" width="191" llx="157" lly="463" urx="285" ury="718"/>
<char name="r" width="333" llx="77" lly="0" urx="446" ury="538"/>
<char name="registered" width="737" llx="54" lly="-19" urx="837" ury="737"/>
<char name="ring" width="333" llx="214" lly="572" urx="402" ury="756"/>
<char name="s" width="500" llx="63" lly="-15" urx="529" ury="538"/>
<char name="scaron" width="500" llx="63" lly="-15" urx="552" ury="734"/>
<char name="section" width="556" llx="76" lly="-191" urx="584" ury="737"/>
<char name="semicolon" width="278" llx="56" lly="-147" urx="301" ury="516"/>
<char name="seven" width="556" llx="137" lly="0" urx="669" ury="688"/>
<char name="six" width="556" llx="91" lly="-19" urx="615" ury="703"/>
<char name="slash" width="278" llx="-21" lly="-19" urx="452" ury="737"/>
<char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="278"/>
<char name="sterling" width="556"/>
<char name="t" width="278"/>
<char name="thorn" width="556"/>
<char name="three" width="556"/>
<char name="threequarters" width="834"/>
<char name="threesuperior" width="333"/>
<char name="tilde" width="333"/>
<char name="trademark" width="1000"/>
<char name="two" width="556"/>
<char name="twosuperior" width="333"/>
<char name="u" width="556"/>
<char name="uacute" width="556"/>
<char name="ucircumflex" width="556"/>
<char name="udieresis" width="556"/>
<char name="ugrave" width="556"/>
<char name="underscore" width="556"/>
<char name="v" width="500"/>
<char name="w" width="722"/>
<char name="x" width="500"/>
<char name="y" width="500"/>
<char name="yacute" width="500"/>
<char name="ydieresis" width="500"/>
<char name="yen" width="556"/>
<char name="z" width="500"/>
<char name="zcaron" width="500"/>
<char name="zero" width="556"/>
</widths>
<char name="sterling" width="556" llx="49" lly="-16" urx="634" ury="718"/>
<char name="t" width="278" llx="102" lly="-7" urx="368" ury="669"/>
<char name="thorn" width="556" llx="14" lly="-207" urx="584" ury="718"/>
<char name="three" width="556" llx="75" lly="-19" urx="610" ury="703"/>
<char name="threequarters" width="834" llx="130" lly="-19" urx="861" ury="703"/>
<char name="threesuperior" width="333" llx="90" lly="270" urx="436" ury="703"/>
<char name="tilde" width="333" llx="125" lly="606" urx="490" ury="722"/>
<char name="trademark" width="1000" llx="186" lly="306" urx="1056" ury="718"/>
<char name="two" width="556" llx="26" lly="0" urx="617" ury="703"/>
<char name="twosuperior" width="333" llx="64" lly="281" urx="449" ury="703"/>
<char name="u" width="556" llx="94" lly="-15" urx="600" ury="523"/>
<char name="uacute" width="556" llx="94" lly="-15" urx="600" ury="734"/>
<char name="ucircumflex" width="556" llx="94" lly="-15" urx="600" ury="734"/>
<char name="udieresis" width="556" llx="94" lly="-15" urx="600" ury="706"/>
<char name="ugrave" width="556" llx="94" lly="-15" urx="600" ury="734"/>
<char name="underscore" width="556" llx="-27" lly="-125" urx="540" ury="-75"/>
<char name="v" width="500" llx="119" lly="0" urx="603" ury="523"/>
<char name="w" width="722" llx="125" lly="0" urx="820" ury="523"/>
<char name="x" width="500" llx="11" lly="0" urx="594" ury="523"/>
<char name="y" width="500" llx="15" lly="-214" urx="600" ury="523"/>
<char name="yacute" width="500" llx="15" lly="-214" urx="600" ury="734"/>
<char name="ydieresis" width="500" llx="15" lly="-214" urx="600" ury="706"/>
<char name="yen" width="556" llx="81" lly="0" urx="699" ury="688"/>
<char name="z" width="500" llx="31" lly="0" urx="571" ury="523"/>
<char name="zcaron" width="500" llx="31" lly="0" urx="571" ury="734"/>
<char name="zero" width="556" llx="93" lly="-19" urx="608" ury="703"/>
</char-metrics>
<kerning kpx1="107">
<pair kern="-20" kpx2="111"/>
<pair kern="-20" kpx2="101"/>
@@ -602,4 +603,4 @@
<pair kern="-30" kpx2="118"/>
<pair kern="-15" kpx2="44"/>
</kerning>
</font-metrics>
</font-metrics>

+ 194
- 193
src/codegen/fonts/Symbol.xml View File

@@ -21,203 +21,204 @@
<family-name>Symbol</family-name>
<class-name>Symbol</class-name>
<encoding>SymbolEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>1010</cap-height>
<x-height>520</x-height>
<ascender>1010</ascender>
<descender>-293</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="space" width="250"/>
<char name="exclam" width="333"/>
<char name="universal" width="713"/>
<char name="numbersign" width="500"/>
<char name="existential" width="549"/>
<char name="percent" width="833"/>
<char name="ampersand" width="778"/>
<char name="suchthat" width="439"/>
<char name="parenleft" width="333"/>
<char name="parenright" width="333"/>
<char name="asteriskmath" width="500"/>
<char name="plus" width="549"/>
<char name="comma" width="250"/>
<char name="minus" width="549"/>
<char name="period" width="250"/>
<char name="slash" width="278"/>
<char name="zero" width="500"/>
<char name="one" width="500"/>
<char name="two" width="500"/>
<char name="three" width="500"/>
<char name="four" width="500"/>
<char name="five" width="500"/>
<char name="six" width="500"/>
<char name="seven" width="500"/>
<char name="eight" width="500"/>
<char name="nine" width="500"/>
<char name="colon" width="278"/>
<char name="semicolon" width="278"/>
<char name="less" width="549"/>
<char name="equal" width="549"/>
<char name="greater" width="549"/>
<char name="question" width="444"/>
<char name="congruent" width="549"/>
<char name="Alpha" width="722"/>
<char name="Beta" width="667"/>
<char name="Chi" width="722"/>
<char name="Delta" width="612"/>
<char name="Epsilon" width="611"/>
<char name="Phi" width="763"/>
<char name="Gamma" width="603"/>
<char name="Eta" width="722"/>
<char name="Iota" width="333"/>
<char name="theta1" width="631"/>
<char name="Kappa" width="722"/>
<char name="Lambda" width="686"/>
<char name="Mu" width="889"/>
<char name="Nu" width="722"/>
<char name="Omicron" width="722"/>
<char name="Pi" width="768"/>
<char name="Theta" width="741"/>
<char name="Rho" width="556"/>
<char name="Sigma" width="592"/>
<char name="Tau" width="611"/>
<char name="Upsilon" width="690"/>
<char name="sigma1" width="439"/>
<char name="Omega" width="768"/>
<char name="Xi" width="645"/>
<char name="Psi" width="795"/>
<char name="Zeta" width="611"/>
<char name="bracketleft" width="333"/>
<char name="therefore" width="863"/>
<char name="bracketright" width="333"/>
<char name="perpendicular" width="658"/>
<char name="underscore" width="500"/>
<char name="radicalex" width="500"/>
<char name="alpha" width="631"/>
<char name="beta" width="549"/>
<char name="chi" width="549"/>
<char name="delta" width="494"/>
<char name="epsilon" width="439"/>
<char name="phi" width="521"/>
<char name="gamma" width="411"/>
<char name="eta" width="603"/>
<char name="iota" width="329"/>
<char name="phi1" width="603"/>
<char name="kappa" width="549"/>
<char name="lambda" width="549"/>
<char name="m" width="576"/>
<char name="mu" width="576"/>
<char name="nu" width="521"/>
<char name="omicron" width="549"/>
<char name="pi" width="549"/>
<char name="theta" width="521"/>
<char name="rho" width="549"/>
<char name="sigma" width="603"/>
<char name="tau" width="439"/>
<char name="upsilon" width="576"/>
<char name="omega1" width="713"/>
<char name="omega" width="686"/>
<char name="xi" width="493"/>
<char name="psi" width="686"/>
<char name="zeta" width="494"/>
<char name="braceleft" width="480"/>
<char name="bar" width="200"/>
<char name="braceright" width="480"/>
<char name="similar" width="549"/>
<char name="Euro" width="750"/>
<char name="Upsilon1" width="620"/>
<char name="minute" width="247"/>
<char name="lessequal" width="549"/>
<char name="fraction" width="167"/>
<char name="infinity" width="713"/>
<char name="florin" width="500"/>
<char name="club" width="753"/>
<char name="diamond" width="753"/>
<char name="heart" width="753"/>
<char name="spade" width="753"/>
<char name="arrowboth" width="1042"/>
<char name="arrowleft" width="987"/>
<char name="arrowup" width="603"/>
<char name="arrowright" width="987"/>
<char name="arrowdown" width="603"/>
<char name="degree" width="400"/>
<char name="plusminus" width="549"/>
<char name="second" width="411"/>
<char name="greaterequal" width="549"/>
<char name="multiply" width="549"/>
<char name="proportional" width="713"/>
<char name="partialdiff" width="494"/>
<char name="bullet" width="460"/>
<char name="divide" width="549"/>
<char name="notequal" width="549"/>
<char name="equivalence" width="549"/>
<char name="approxequal" width="549"/>
<char name="ellipsis" width="1000"/>
<char name="arrowvertex" width="603"/>
<char name="arrowhorizex" width="1000"/>
<char name="carriagereturn" width="658"/>
<char name="aleph" width="823"/>
<char name="Ifraktur" width="686"/>
<char name="Rfraktur" width="795"/>
<char name="weierstrass" width="987"/>
<char name="circlemultiply" width="768"/>
<char name="circleplus" width="768"/>
<char name="emptyset" width="823"/>
<char name="intersection" width="768"/>
<char name="union" width="768"/>
<char name="propersuperset" width="713"/>
<char name="reflexsuperset" width="713"/>
<char name="notsubset" width="713"/>
<char name="propersubset" width="713"/>
<char name="reflexsubset" width="713"/>
<char name="element" width="713"/>
<char name="notelement" width="713"/>
<char name="angle" width="768"/>
<char name="gradient" width="713"/>
<char name="registerserif" width="790"/>
<char name="copyrightserif" width="790"/>
<char name="trademarkserif" width="890"/>
<char name="product" width="823"/>
<char name="radical" width="549"/>
<char name="dotmath" width="250"/>
<char name="logicalnot" width="713"/>
<char name="logicaland" width="603"/>
<char name="logicalor" width="603"/>
<char name="arrowdblboth" width="1042"/>
<char name="arrowdblleft" width="987"/>
<char name="arrowdblup" width="603"/>
<char name="arrowdblright" width="987"/>
<char name="arrowdbldown" width="603"/>
<char name="lozenge" width="494"/>
<char name="angleleft" width="329"/>
<char name="registersans" width="790"/>
<char name="copyrightsans" width="790"/>
<char name="trademarksans" width="786"/>
<char name="summation" width="713"/>
<char name="parenlefttp" width="384"/>
<char name="parenleftex" width="384"/>
<char name="parenleftbt" width="384"/>
<char name="bracketlefttp" width="384"/>
<char name="bracketleftex" width="384"/>
<char name="bracketleftbt" width="384"/>
<char name="bracelefttp" width="494"/>
<char name="braceleftmid" width="494"/>
<char name="braceleftbt" width="494"/>
<char name="braceex" width="494"/>
<char name="angleright" width="329"/>
<char name="integral" width="274"/>
<char name="integraltp" width="686"/>
<char name="integralex" width="686"/>
<char name="integralbt" width="686"/>
<char name="parenrighttp" width="384"/>
<char name="parenrightex" width="384"/>
<char name="parenrightbt" width="384"/>
<char name="bracketrighttp" width="384"/>
<char name="bracketrightex" width="384"/>
<char name="bracketrightbt" width="384"/>
<char name="bracerighttp" width="494"/>
<char name="bracerightmid" width="494"/>
<char name="bracerightbt" width="494"/>
<char name="apple" width="790"/>
</widths>
<char-metrics>
<char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
<char name="exclam" width="333" llx="128" lly="-17" urx="240" ury="672"/>
<char name="universal" width="713" llx="31" lly="0" urx="681" ury="705"/>
<char name="numbersign" width="500" llx="20" lly="-16" urx="481" ury="673"/>
<char name="existential" width="549" llx="25" lly="0" urx="478" ury="707"/>
<char name="percent" width="833" llx="63" lly="-36" urx="771" ury="655"/>
<char name="ampersand" width="778" llx="41" lly="-18" urx="750" ury="661"/>
<char name="suchthat" width="439" llx="48" lly="-17" urx="414" ury="500"/>
<char name="parenleft" width="333" llx="53" lly="-191" urx="300" ury="673"/>
<char name="parenright" width="333" llx="30" lly="-191" urx="277" ury="673"/>
<char name="asteriskmath" width="500" llx="65" lly="134" urx="427" ury="551"/>
<char name="plus" width="549" llx="10" lly="0" urx="539" ury="533"/>
<char name="comma" width="250" llx="56" lly="-152" urx="194" ury="104"/>
<char name="minus" width="549" llx="11" lly="233" urx="535" ury="288"/>
<char name="period" width="250" llx="69" lly="-17" urx="181" ury="95"/>
<char name="slash" width="278" llx="0" lly="-18" urx="254" ury="646"/>
<char name="zero" width="500" llx="24" lly="-14" urx="476" ury="685"/>
<char name="one" width="500" llx="117" lly="0" urx="390" ury="673"/>
<char name="two" width="500" llx="25" lly="0" urx="475" ury="685"/>
<char name="three" width="500" llx="43" lly="-14" urx="435" ury="685"/>
<char name="four" width="500" llx="15" lly="0" urx="469" ury="685"/>
<char name="five" width="500" llx="32" lly="-14" urx="445" ury="690"/>
<char name="six" width="500" llx="34" lly="-14" urx="468" ury="685"/>
<char name="seven" width="500" llx="24" lly="-16" urx="448" ury="673"/>
<char name="eight" width="500" llx="56" lly="-14" urx="445" ury="685"/>
<char name="nine" width="500" llx="30" lly="-18" urx="459" ury="685"/>
<char name="colon" width="278" llx="81" lly="-17" urx="193" ury="460"/>
<char name="semicolon" width="278" llx="83" lly="-152" urx="221" ury="460"/>
<char name="less" width="549" llx="26" lly="0" urx="523" ury="522"/>
<char name="equal" width="549" llx="11" lly="141" urx="537" ury="390"/>
<char name="greater" width="549" llx="26" lly="0" urx="523" ury="522"/>
<char name="question" width="444" llx="70" lly="-17" urx="412" ury="686"/>
<char name="congruent" width="549" llx="11" lly="0" urx="537" ury="475"/>
<char name="Alpha" width="722" llx="4" lly="0" urx="684" ury="673"/>
<char name="Beta" width="667" llx="29" lly="0" urx="592" ury="673"/>
<char name="Chi" width="722" llx="-9" lly="0" urx="704" ury="673"/>
<char name="Delta" width="612" llx="6" lly="0" urx="608" ury="688"/>
<char name="Epsilon" width="611" llx="32" lly="0" urx="617" ury="673"/>
<char name="Phi" width="763" llx="26" lly="0" urx="741" ury="673"/>
<char name="Gamma" width="603" llx="24" lly="0" urx="609" ury="673"/>
<char name="Eta" width="722" llx="39" lly="0" urx="729" ury="673"/>
<char name="Iota" width="333" llx="32" lly="0" urx="316" ury="673"/>
<char name="theta1" width="631" llx="18" lly="-18" urx="623" ury="689"/>
<char name="Kappa" width="722" llx="35" lly="0" urx="722" ury="673"/>
<char name="Lambda" width="686" llx="6" lly="0" urx="680" ury="688"/>
<char name="Mu" width="889" llx="28" lly="0" urx="887" ury="673"/>
<char name="Nu" width="722" llx="29" lly="-8" urx="720" ury="673"/>
<char name="Omicron" width="722" llx="41" lly="-17" urx="715" ury="685"/>
<char name="Pi" width="768" llx="25" lly="0" urx="745" ury="673"/>
<char name="Theta" width="741" llx="41" lly="-17" urx="715" ury="685"/>
<char name="Rho" width="556" llx="28" lly="0" urx="563" ury="673"/>
<char name="Sigma" width="592" llx="5" lly="0" urx="589" ury="673"/>
<char name="Tau" width="611" llx="33" lly="0" urx="607" ury="673"/>
<char name="Upsilon" width="690" llx="-8" lly="0" urx="694" ury="673"/>
<char name="sigma1" width="439" llx="40" lly="-233" urx="436" ury="500"/>
<char name="Omega" width="768" llx="34" lly="0" urx="736" ury="688"/>
<char name="Xi" width="645" llx="40" lly="0" urx="599" ury="673"/>
<char name="Psi" width="795" llx="15" lly="0" urx="781" ury="684"/>
<char name="Zeta" width="611" llx="44" lly="0" urx="636" ury="673"/>
<char name="bracketleft" width="333" llx="86" lly="-155" urx="299" ury="674"/>
<char name="therefore" width="863" llx="163" lly="0" urx="701" ury="487"/>
<char name="bracketright" width="333" llx="33" lly="-155" urx="246" ury="674"/>
<char name="perpendicular" width="658" llx="15" lly="0" urx="652" ury="674"/>
<char name="underscore" width="500" llx="-2" lly="-125" urx="502" ury="-75"/>
<char name="radicalex" width="500" llx="480" lly="881" urx="1090" ury="917"/>
<char name="alpha" width="631" llx="41" lly="-18" urx="622" ury="500"/>
<char name="beta" width="549" llx="61" lly="-223" urx="515" ury="741"/>
<char name="chi" width="549" llx="12" lly="-231" urx="522" ury="499"/>
<char name="delta" width="494" llx="40" lly="-19" urx="481" ury="740"/>
<char name="epsilon" width="439" llx="22" lly="-19" urx="427" ury="502"/>
<char name="phi" width="521" llx="28" lly="-224" urx="492" ury="673"/>
<char name="gamma" width="411" llx="5" lly="-225" urx="484" ury="499"/>
<char name="eta" width="603" llx="0" lly="-202" urx="527" ury="514"/>
<char name="iota" width="329" llx="0" lly="-17" urx="301" ury="503"/>
<char name="phi1" width="603" llx="36" lly="-224" urx="587" ury="499"/>
<char name="kappa" width="549" llx="33" lly="0" urx="558" ury="501"/>
<char name="lambda" width="549" llx="24" lly="-17" urx="548" ury="739"/>
<char name="mu" width="576" llx="33" lly="-223" urx="567" ury="500"/>
<char name="nu" width="521" llx="-9" lly="-16" urx="475" ury="507"/>
<char name="omicron" width="549" llx="35" lly="-19" urx="501" ury="499"/>
<char name="pi" width="549" llx="10" lly="-19" urx="530" ury="487"/>
<char name="theta" width="521" llx="43" lly="-17" urx="485" ury="690"/>
<char name="rho" width="549" llx="50" lly="-230" urx="490" ury="499"/>
<char name="sigma" width="603" llx="30" lly="-21" urx="588" ury="500"/>
<char name="tau" width="439" llx="10" lly="-19" urx="418" ury="500"/>
<char name="upsilon" width="576" llx="7" lly="-18" urx="535" ury="507"/>
<char name="omega1" width="713" llx="12" lly="-18" urx="671" ury="583"/>
<char name="omega" width="686" llx="42" lly="-17" urx="684" ury="500"/>
<char name="xi" width="493" llx="27" lly="-224" urx="469" ury="766"/>
<char name="psi" width="686" llx="12" lly="-228" urx="701" ury="500"/>
<char name="zeta" width="494" llx="60" lly="-225" urx="467" ury="756"/>
<char name="braceleft" width="480" llx="58" lly="-183" urx="397" ury="673"/>
<char name="bar" width="200" llx="65" lly="-293" urx="135" ury="707"/>
<char name="braceright" width="480" llx="79" lly="-183" urx="418" ury="673"/>
<char name="similar" width="549" llx="17" lly="203" urx="529" ury="307"/>
<char name="Euro" width="750" llx="20" lly="-12" urx="714" ury="685"/>
<char name="Upsilon1" width="620" llx="-2" lly="0" urx="610" ury="685"/>
<char name="minute" width="247" llx="27" lly="459" urx="228" ury="735"/>
<char name="lessequal" width="549" llx="29" lly="0" urx="526" ury="639"/>
<char name="fraction" width="167" llx="-180" lly="-12" urx="340" ury="677"/>
<char name="infinity" width="713" llx="26" lly="124" urx="688" ury="404"/>
<char name="florin" width="500" llx="2" lly="-193" urx="494" ury="686"/>
<char name="club" width="753" llx="86" lly="-26" urx="660" ury="533"/>
<char name="diamond" width="753" llx="142" lly="-36" urx="600" ury="550"/>
<char name="heart" width="753" llx="117" lly="-33" urx="631" ury="532"/>
<char name="spade" width="753" llx="113" lly="-36" urx="629" ury="548"/>
<char name="arrowboth" width="1042" llx="24" lly="-15" urx="1024" ury="511"/>
<char name="arrowleft" width="987" llx="32" lly="-15" urx="942" ury="511"/>
<char name="arrowup" width="603" llx="45" lly="0" urx="571" ury="910"/>
<char name="arrowright" width="987" llx="49" lly="-15" urx="959" ury="511"/>
<char name="arrowdown" width="603" llx="45" lly="-22" urx="571" ury="888"/>
<char name="degree" width="400" llx="50" lly="385" urx="350" ury="685"/>
<char name="plusminus" width="549" llx="10" lly="0" urx="539" ury="645"/>
<char name="second" width="411" llx="20" lly="459" urx="413" ury="737"/>
<char name="greaterequal" width="549" llx="29" lly="0" urx="526" ury="639"/>
<char name="multiply" width="549" llx="17" lly="8" urx="533" ury="524"/>
<char name="proportional" width="713" llx="27" lly="123" urx="639" ury="404"/>
<char name="partialdiff" width="494" llx="26" lly="-20" urx="462" ury="746"/>
<char name="bullet" width="460" llx="50" lly="113" urx="410" ury="473"/>
<char name="divide" width="549" llx="10" lly="71" urx="536" ury="456"/>
<char name="notequal" width="549" llx="15" lly="-25" urx="540" ury="549"/>
<char name="equivalence" width="549" llx="14" lly="82" urx="538" ury="443"/>
<char name="approxequal" width="549" llx="14" lly="135" urx="527" ury="394"/>
<char name="ellipsis" width="1000" llx="111" lly="-17" urx="889" ury="95"/>
<char name="arrowvertex" width="603" llx="280" lly="-120" urx="336" ury="1010"/>
<char name="arrowhorizex" width="1000" llx="-60" lly="220" urx="1050" ury="276"/>
<char name="carriagereturn" width="658" llx="15" lly="-16" urx="602" ury="629"/>
<char name="aleph" width="823" llx="175" lly="-18" urx="661" ury="658"/>
<char name="Ifraktur" width="686" llx="10" lly="-53" urx="578" ury="740"/>
<char name="Rfraktur" width="795" llx="26" lly="-15" urx="759" ury="734"/>
<char name="weierstrass" width="987" llx="159" lly="-211" urx="870" ury="573"/>
<char name="circlemultiply" width="768" llx="43" lly="-17" urx="733" ury="673"/>
<char name="circleplus" width="768" llx="43" lly="-15" urx="733" ury="675"/>
<char name="emptyset" width="823" llx="39" lly="-24" urx="781" ury="719"/>
<char name="intersection" width="768" llx="40" lly="0" urx="732" ury="509"/>
<char name="union" width="768" llx="40" lly="-17" urx="732" ury="492"/>
<char name="propersuperset" width="713" llx="20" lly="0" urx="673" ury="470"/>
<char name="reflexsuperset" width="713" llx="20" lly="-125" urx="673" ury="470"/>
<char name="notsubset" width="713" llx="36" lly="-70" urx="690" ury="540"/>
<char name="propersubset" width="713" llx="37" lly="0" urx="690" ury="470"/>
<char name="reflexsubset" width="713" llx="37" lly="-125" urx="690" ury="470"/>
<char name="element" width="713" llx="45" lly="0" urx="505" ury="468"/>
<char name="notelement" width="713" llx="45" lly="-58" urx="505" ury="555"/>
<char name="angle" width="768" llx="26" lly="0" urx="738" ury="673"/>
<char name="gradient" width="713" llx="36" lly="-19" urx="681" ury="718"/>
<char name="registerserif" width="790" llx="50" lly="-17" urx="740" ury="673"/>
<char name="copyrightserif" width="790" llx="51" lly="-15" urx="741" ury="675"/>
<char name="trademarkserif" width="890" llx="18" lly="293" urx="855" ury="673"/>
<char name="product" width="823" llx="25" lly="-101" urx="803" ury="751"/>
<char name="radical" width="549" llx="10" lly="-38" urx="515" ury="917"/>
<char name="dotmath" width="250" llx="69" lly="210" urx="169" ury="310"/>
<char name="logicalnot" width="713" llx="15" lly="0" urx="680" ury="288"/>
<char name="logicaland" width="603" llx="23" lly="0" urx="583" ury="454"/>
<char name="logicalor" width="603" llx="30" lly="0" urx="578" ury="477"/>
<char name="arrowdblboth" width="1042" llx="27" lly="-20" urx="1023" ury="510"/>
<char name="arrowdblleft" width="987" llx="30" lly="-15" urx="939" ury="513"/>
<char name="arrowdblup" width="603" llx="39" lly="2" urx="567" ury="911"/>
<char name="arrowdblright" width="987" llx="45" lly="-20" urx="954" ury="508"/>
<char name="arrowdbldown" width="603" llx="44" lly="-19" urx="572" ury="890"/>
<char name="lozenge" width="494" llx="18" lly="0" urx="466" ury="745"/>
<char name="angleleft" width="329" llx="25" lly="-198" urx="306" ury="746"/>
<char name="registersans" width="790" llx="50" lly="-20" urx="740" ury="670"/>
<char name="copyrightsans" width="790" llx="49" lly="-15" urx="739" ury="675"/>
<char name="trademarksans" width="786" llx="5" lly="293" urx="725" ury="673"/>
<char name="summation" width="713" llx="14" lly="-108" urx="695" ury="752"/>
<char name="parenlefttp" width="384" llx="24" lly="-293" urx="436" ury="926"/>
<char name="parenleftex" width="384" llx="24" lly="-85" urx="108" ury="925"/>
<char name="parenleftbt" width="384" llx="24" lly="-293" urx="436" ury="926"/>
<char name="bracketlefttp" width="384" llx="0" lly="-80" urx="349" ury="926"/>
<char name="bracketleftex" width="384" llx="0" lly="-79" urx="77" ury="925"/>
<char name="bracketleftbt" width="384" llx="0" lly="-80" urx="349" ury="926"/>
<char name="bracelefttp" width="494" llx="209" lly="-85" urx="445" ury="925"/>
<char name="braceleftmid" width="494" llx="20" lly="-85" urx="284" ury="935"/>
<char name="braceleftbt" width="494" llx="209" lly="-75" urx="445" ury="935"/>
<char name="braceex" width="494" llx="209" lly="-85" urx="284" ury="935"/>
<char name="angleright" width="329" llx="21" lly="-198" urx="302" ury="746"/>
<char name="integral" width="274" llx="2" lly="-107" urx="291" ury="916"/>
<char name="integraltp" width="686" llx="308" lly="-88" urx="675" ury="920"/>
<char name="integralex" width="686" llx="308" lly="-88" urx="378" ury="975"/>
<char name="integralbt" width="686" llx="11" lly="-87" urx="378" ury="921"/>
<char name="parenrighttp" width="384" llx="54" lly="-293" urx="466" ury="926"/>
<char name="parenrightex" width="384" llx="382" lly="-85" urx="466" ury="925"/>
<char name="parenrightbt" width="384" llx="54" lly="-293" urx="466" ury="926"/>
<char name="bracketrighttp" width="384" llx="22" lly="-80" urx="371" ury="926"/>
<char name="bracketrightex" width="384" llx="294" lly="-79" urx="371" ury="925"/>
<char name="bracketrightbt" width="384" llx="22" lly="-80" urx="371" ury="926"/>
<char name="bracerighttp" width="494" llx="48" lly="-85" urx="284" ury="925"/>
<char name="bracerightmid" width="494" llx="209" lly="-85" urx="473" ury="935"/>
<char name="bracerightbt" width="494" llx="48" lly="-75" urx="284" ury="935"/>
<char name="apple" width="790" llx="56" lly="-3" urx="733" ury="808"/>
</char-metrics>
</font-metrics>

+ 233
- 232
src/codegen/fonts/TimesBold.xml View File

@@ -22,245 +22,246 @@
<family-name>Times</family-name>
<class-name>TimesBold</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>676</cap-height>
<x-height>461</x-height>
<ascender>676</ascender>
<descender>-205</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="722"/>
<char name="AE" width="1000"/>
<char name="Aacute" width="722"/>
<char name="Acircumflex" width="722"/>
<char name="Adieresis" width="722"/>
<char name="Agrave" width="722"/>
<char name="Aring" width="722"/>
<char name="Atilde" width="722"/>
<char name="B" width="667"/>
<char name="C" width="722"/>
<char name="Ccedilla" width="722"/>
<char name="D" width="722"/>
<char name="E" width="667"/>
<char name="Eacute" width="667"/>
<char name="Ecircumflex" width="667"/>
<char name="Edieresis" width="667"/>
<char name="Egrave" width="667"/>
<char name="Eth" width="722"/>
<char name="Euro" width="500"/>
<char name="F" width="611"/>
<char name="G" width="778"/>
<char name="H" width="778"/>
<char name="I" width="389"/>
<char name="Iacute" width="389"/>
<char name="Icircumflex" width="389"/>
<char name="Idieresis" width="389"/>
<char name="Igrave" width="389"/>
<char name="J" width="500"/>
<char name="K" width="778"/>
<char name="L" width="667"/>
<char name="Lslash" width="667"/>
<char name="M" width="944"/>
<char name="N" width="722"/>
<char name="Ntilde" width="722"/>
<char name="O" width="778"/>
<char name="OE" width="1000"/>
<char name="Oacute" width="778"/>
<char name="Ocircumflex" width="778"/>
<char name="Odieresis" width="778"/>
<char name="Ograve" width="778"/>
<char name="Oslash" width="778"/>
<char name="Otilde" width="778"/>
<char name="P" width="611"/>
<char name="Q" width="778"/>
<char name="R" width="722"/>
<char name="S" width="556"/>
<char name="Scaron" width="556"/>
<char name="T" width="667"/>
<char name="Thorn" width="611"/>
<char name="U" width="722"/>
<char name="Uacute" width="722"/>
<char name="Ucircumflex" width="722"/>
<char name="Udieresis" width="722"/>
<char name="Ugrave" width="722"/>
<char name="V" width="722"/>
<char name="W" width="1000"/>
<char name="X" width="722"/>
<char name="Y" width="722"/>
<char name="Yacute" width="722"/>
<char name="Ydieresis" width="722"/>
<char name="Z" width="667"/>
<char name="Zcaron" width="667"/>
<char name="a" width="500"/>
<char name="aacute" width="500"/>
<char name="acircumflex" width="500"/>
<char name="acute" width="333"/>
<char name="adieresis" width="500"/>
<char name="ae" width="722"/>
<char name="agrave" width="500"/>
<char name="ampersand" width="833"/>
<char name="aring" width="500"/>
<char name="asciicircum" width="581"/>
<char name="asciitilde" width="520"/>
<char name="asterisk" width="500"/>
<char name="at" width="930"/>
<char name="atilde" width="500"/>
<char name="b" width="556"/>
<char name="backslash" width="278"/>
<char name="bar" width="220"/>
<char name="braceleft" width="394"/>
<char name="braceright" width="394"/>
<char name="bracketleft" width="333"/>
<char name="bracketright" width="333"/>
<char name="breve" width="333"/>
<char name="brokenbar" width="220"/>
<char name="bullet" width="350"/>
<char name="c" width="444"/>
<char name="caron" width="333"/>
<char name="ccedilla" width="444"/>
<char name="cedilla" width="333"/>
<char name="cent" width="500"/>
<char name="circumflex" width="333"/>
<char name="colon" width="333"/>
<char name="comma" width="250"/>
<char name="copyright" width="747"/>
<char name="currency" width="500"/>
<char name="d" width="556"/>
<char name="dagger" width="500"/>
<char name="daggerdbl" width="500"/>
<char name="degree" width="400"/>
<char name="dieresis" width="333"/>
<char name="divide" width="570"/>
<char name="dollar" width="500"/>
<char name="dotaccent" width="333"/>
<char name="dotlessi" width="278"/>
<char name="e" width="444"/>
<char name="eacute" width="444"/>
<char name="ecircumflex" width="444"/>
<char name="edieresis" width="444"/>
<char name="egrave" width="444"/>
<char name="eight" width="500"/>
<char name="ellipsis" width="1000"/>
<char name="emdash" width="1000"/>
<char name="endash" width="500"/>
<char name="equal" width="570"/>
<char name="eth" width="500"/>
<char name="exclam" width="333"/>
<char name="exclamdown" width="333"/>
<char name="f" width="333"/>
<char name="fi" width="556"/>
<char name="five" width="500"/>
<char name="fl" width="556"/>
<char name="florin" width="500"/>
<char name="four" width="500"/>
<char name="fraction" width="167"/>
<char name="g" width="500"/>
<char name="germandbls" width="556"/>
<char name="grave" width="333"/>
<char name="greater" width="570"/>
<char name="guillemotleft" width="500"/>
<char name="guillemotright" width="500"/>
<char name="guilsinglleft" width="333"/>
<char name="guilsinglright" width="333"/>
<char name="h" width="556"/>
<char name="hungarumlaut" width="333"/>
<char name="hyphen" width="333"/>
<char name="i" width="278"/>
<char name="iacute" width="278"/>
<char name="icircumflex" width="278"/>
<char name="idieresis" width="278"/>
<char name="igrave" width="278"/>
<char name="j" width="333"/>
<char name="k" width="556"/>
<char name="l" width="278"/>
<char name="less" width="570"/>
<char name="logicalnot" width="570"/>
<char name="lslash" width="278"/>
<char name="m" width="833"/>
<char name="macron" width="333"/>
<char name="minus" width="324"/>
<char name="mu" width="556"/>
<char name="multiply" width="570"/>
<char name="n" width="556"/>
<char name="nine" width="500"/>
<char name="ntilde" width="556"/>
<char name="numbersign" width="500"/>
<char name="o" width="500"/>
<char name="oacute" width="500"/>
<char name="ocircumflex" width="500"/>
<char name="odieresis" width="500"/>
<char name="oe" width="722"/>
<char name="ogonek" width="333"/>
<char name="ograve" width="500"/>
<char name="one" width="500"/>
<char name="onehalf" width="750"/>
<char name="onequarter" width="750"/>
<char name="onesuperior" width="300"/>
<char name="ordfeminine" width="300"/>
<char name="ordmasculine" width="330"/>
<char name="oslash" width="500"/>
<char name="otilde" width="500"/>
<char name="p" width="556"/>
<char name="paragraph" width="540"/>
<char name="parenleft" width="333"/>
<char name="parenright" width="333"/>
<char name="percent" width="1000"/>
<char name="period" width="250"/>
<char name="periodcentered" width="250"/>
<char name="perthousand" width="1000"/>
<char name="plus" width="570"/>
<char name="plusminus" width="570"/>
<char name="q" width="556"/>
<char name="question" width="500"/>
<char name="questiondown" width="500"/>
<char name="quotedbl" width="555"/>
<char name="quotedblbase" width="500"/>
<char name="quotedblleft" width="500"/>
<char name="quotedblright" width="500"/>
<char name="quoteleft" width="333"/>
<char name="quoteright" width="333"/>
<char name="quotesinglbase" width="333"/>
<char name="quotesingle" width="278"/>
<char name="r" width="444"/>
<char name="registered" width="747"/>
<char name="ring" width="333"/>
<char name="s" width="389"/>
<char name="scaron" width="389"/>
<char name="section" width="500"/>
<char name="semicolon" width="333"/>
<char name="seven" width="500"/>
<char name="six" width="500"/>
<char name="slash" width="278"/>
<char name="space" width="250"/>
<char-metrics>
<char name="A" width="722" llx="9" lly="0" urx="689" ury="690"/>
<char name="AE" width="1000" llx="4" lly="0" urx="951" ury="676"/>
<char name="Aacute" width="722" llx="9" lly="0" urx="689" ury="923"/>
<char name="Acircumflex" width="722" llx="9" lly="0" urx="689" ury="914"/>
<char name="Adieresis" width="722" llx="9" lly="0" urx="689" ury="877"/>
<char name="Agrave" width="722" llx="9" lly="0" urx="689" ury="923"/>
<char name="Aring" width="722" llx="9" lly="0" urx="689" ury="935"/>
<char name="Atilde" width="722" llx="9" lly="0" urx="689" ury="884"/>
<char name="B" width="667" llx="16" lly="0" urx="619" ury="676"/>
<char name="C" width="722" llx="49" lly="-19" urx="687" ury="691"/>
<char name="Ccedilla" width="722" llx="49" lly="-218" urx="687" ury="691"/>
<char name="D" width="722" llx="14" lly="0" urx="690" ury="676"/>
<char name="E" width="667" llx="16" lly="0" urx="641" ury="676"/>
<char name="Eacute" width="667" llx="16" lly="0" urx="641" ury="923"/>
<char name="Ecircumflex" width="667" llx="16" lly="0" urx="641" ury="914"/>
<char name="Edieresis" width="667" llx="16" lly="0" urx="641" ury="877"/>
<char name="Egrave" width="667" llx="16" lly="0" urx="641" ury="923"/>
<char name="Eth" width="722" llx="6" lly="0" urx="690" ury="676"/>
<char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="611" llx="16" lly="0" urx="583" ury="676"/>
<char name="G" width="778" llx="37" lly="-19" urx="755" ury="691"/>
<char name="H" width="778" llx="21" lly="0" urx="759" ury="676"/>
<char name="I" width="389" llx="20" lly="0" urx="370" ury="676"/>
<char name="Iacute" width="389" llx="20" lly="0" urx="370" ury="923"/>
<char name="Icircumflex" width="389" llx="20" lly="0" urx="370" ury="914"/>
<char name="Idieresis" width="389" llx="20" lly="0" urx="370" ury="877"/>
<char name="Igrave" width="389" llx="20" lly="0" urx="370" ury="923"/>
<char name="J" width="500" llx="3" lly="-96" urx="479" ury="676"/>
<char name="K" width="778" llx="30" lly="0" urx="769" ury="676"/>
<char name="L" width="667" llx="19" lly="0" urx="638" ury="676"/>
<char name="Lslash" width="667" llx="19" lly="0" urx="638" ury="676"/>
<char name="M" width="944" llx="14" lly="0" urx="921" ury="676"/>
<char name="N" width="722" llx="16" lly="-18" urx="701" ury="676"/>
<char name="Ntilde" width="722" llx="16" lly="-18" urx="701" ury="884"/>
<char name="O" width="778" llx="35" lly="-19" urx="743" ury="691"/>
<char name="OE" width="1000" llx="22" lly="-5" urx="981" ury="684"/>
<char name="Oacute" width="778" llx="35" lly="-19" urx="743" ury="923"/>
<char name="Ocircumflex" width="778" llx="35" lly="-19" urx="743" ury="914"/>
<char name="Odieresis" width="778" llx="35" lly="-19" urx="743" ury="877"/>
<char name="Ograve" width="778" llx="35" lly="-19" urx="743" ury="923"/>
<char name="Oslash" width="778" llx="35" lly="-74" urx="743" ury="737"/>
<char name="Otilde" width="778" llx="35" lly="-19" urx="743" ury="884"/>
<char name="P" width="611" llx="16" lly="0" urx="600" ury="676"/>
<char name="Q" width="778" llx="35" lly="-176" urx="743" ury="691"/>
<char name="R" width="722" llx="26" lly="0" urx="715" ury="676"/>
<char name="S" width="556" llx="35" lly="-19" urx="513" ury="692"/>
<char name="Scaron" width="556" llx="35" lly="-19" urx="513" ury="914"/>
<char name="T" width="667" llx="31" lly="0" urx="636" ury="676"/>
<char name="Thorn" width="611" llx="16" lly="0" urx="600" ury="676"/>
<char name="U" width="722" llx="16" lly="-19" urx="701" ury="676"/>
<char name="Uacute" width="722" llx="16" lly="-19" urx="701" ury="923"/>
<char name="Ucircumflex" width="722" llx="16" lly="-19" urx="701" ury="914"/>
<char name="Udieresis" width="722" llx="16" lly="-19" urx="701" ury="877"/>
<char name="Ugrave" width="722" llx="16" lly="-19" urx="701" ury="923"/>
<char name="V" width="722" llx="16" lly="-18" urx="701" ury="676"/>
<char name="W" width="1000" llx="19" lly="-15" urx="981" ury="676"/>
<char name="X" width="722" llx="16" lly="0" urx="699" ury="676"/>
<char name="Y" width="722" llx="15" lly="0" urx="699" ury="676"/>
<char name="Yacute" width="722" llx="15" lly="0" urx="699" ury="923"/>
<char name="Ydieresis" width="722" llx="15" lly="0" urx="699" ury="877"/>
<char name="Z" width="667" llx="28" lly="0" urx="634" ury="676"/>
<char name="Zcaron" width="667" llx="28" lly="0" urx="634" ury="914"/>
<char name="a" width="500" llx="25" lly="-14" urx="488" ury="473"/>
<char name="aacute" width="500" llx="25" lly="-14" urx="488" ury="713"/>
<char name="acircumflex" width="500" llx="25" lly="-14" urx="488" ury="704"/>
<char name="acute" width="333" llx="86" lly="528" urx="324" ury="713"/>
<char name="adieresis" width="500" llx="25" lly="-14" urx="488" ury="667"/>
<char name="ae" width="722" llx="33" lly="-14" urx="693" ury="473"/>
<char name="agrave" width="500" llx="25" lly="-14" urx="488" ury="713"/>
<char name="ampersand" width="833" llx="62" lly="-16" urx="787" ury="691"/>
<char name="aring" width="500" llx="25" lly="-14" urx="488" ury="740"/>
<char name="asciicircum" width="581" llx="73" lly="311" urx="509" ury="676"/>
<char name="asciitilde" width="520" llx="29" lly="173" urx="491" ury="333"/>
<char name="asterisk" width="500" llx="56" lly="255" urx="447" ury="691"/>
<char name="at" width="930" llx="108" lly="-19" urx="822" ury="691"/>
<char name="atilde" width="500" llx="25" lly="-14" urx="488" ury="674"/>
<char name="b" width="556" llx="17" lly="-14" urx="521" ury="676"/>
<char name="backslash" width="278" llx="-25" lly="-19" urx="303" ury="691"/>
<char name="bar" width="220" llx="66" lly="-218" urx="154" ury="782"/>
<char name="braceleft" width="394" llx="22" lly="-175" urx="340" ury="698"/>
<char name="braceright" width="394" llx="54" lly="-175" urx="372" ury="698"/>
<char name="bracketleft" width="333" llx="67" lly="-149" urx="301" ury="678"/>
<char name="bracketright" width="333" llx="32" lly="-149" urx="266" ury="678"/>
<char name="breve" width="333" llx="15" lly="528" urx="318" ury="691"/>
<char name="brokenbar" width="220" llx="66" lly="-143" urx="154" ury="707"/>
<char name="bullet" width="350" llx="35" lly="198" urx="315" ury="478"/>
<char name="c" width="444" llx="25" lly="-14" urx="430" ury="473"/>
<char name="caron" width="333" llx="-2" lly="528" urx="335" ury="704"/>
<char name="ccedilla" width="444" llx="25" lly="-218" urx="430" ury="473"/>
<char name="cedilla" width="333" llx="68" lly="-218" urx="294" ury="0"/>
<char name="cent" width="500" llx="53" lly="-140" urx="458" ury="588"/>
<char name="circumflex" width="333" llx="-2" lly="528" urx="335" ury="704"/>
<char name="colon" width="333" llx="82" lly="-13" urx="251" ury="472"/>
<char name="comma" width="250" llx="39" lly="-180" urx="223" ury="155"/>
<char name="copyright" width="747" llx="26" lly="-19" urx="721" ury="691"/>
<char name="currency" width="500" llx="-26" lly="61" urx="526" ury="613"/>
<char name="d" width="556" llx="25" lly="-14" urx="534" ury="676"/>
<char name="dagger" width="500" llx="47" lly="-134" urx="453" ury="691"/>
<char name="daggerdbl" width="500" llx="45" lly="-132" urx="456" ury="691"/>
<char name="degree" width="400" llx="57" lly="402" urx="343" ury="688"/>
<char name="dieresis" width="333" llx="-2" lly="537" urx="335" ury="667"/>
<char name="divide" width="570" llx="33" lly="-31" urx="537" ury="537"/>
<char name="dollar" width="500" llx="29" lly="-99" urx="472" ury="750"/>
<char name="dotaccent" width="333" llx="103" lly="536" urx="258" ury="691"/>
<char name="dotlessi" width="278" llx="16" lly="0" urx="255" ury="461"/>
<char name="e" width="444" llx="25" lly="-14" urx="426" ury="473"/>
<char name="eacute" width="444" llx="25" lly="-14" urx="426" ury="713"/>
<char name="ecircumflex" width="444" llx="25" lly="-14" urx="426" ury="704"/>
<char name="edieresis" width="444" llx="25" lly="-14" urx="426" ury="667"/>
<char name="egrave" width="444" llx="25" lly="-14" urx="426" ury="713"/>
<char name="eight" width="500" llx="28" lly="-13" urx="472" ury="688"/>
<char name="ellipsis" width="1000" llx="82" lly="-13" urx="917" ury="156"/>
<char name="emdash" width="1000" llx="0" lly="181" urx="1000" ury="271"/>
<char name="endash" width="500" llx="0" lly="181" urx="500" ury="271"/>
<char name="equal" width="570" llx="33" lly="107" urx="537" ury="399"/>
<char name="eth" width="500" llx="25" lly="-14" urx="476" ury="691"/>
<char name="exclam" width="333" llx="81" lly="-13" urx="251" ury="691"/>
<char name="exclamdown" width="333" llx="82" lly="-203" urx="252" ury="501"/>
<char name="f" width="333" llx="14" lly="0" urx="389" ury="691"/>
<char name="fi" width="556" llx="14" lly="0" urx="536" ury="691"/>
<char name="five" width="500" llx="22" lly="-8" urx="470" ury="676"/>
<char name="fl" width="556" llx="14" lly="0" urx="536" ury="691"/>
<char name="florin" width="500" llx="0" lly="-155" urx="498" ury="706"/>
<char name="four" width="500" llx="19" lly="0" urx="475" ury="688"/>
<char name="fraction" width="167" llx="-168" lly="-12" urx="329" ury="688"/>
<char name="g" width="500" llx="28" lly="-206" urx="483" ury="473"/>
<char name="germandbls" width="556" llx="19" lly="-12" urx="517" ury="691"/>
<char name="grave" width="333" llx="8" lly="528" urx="246" ury="713"/>
<char name="greater" width="570" llx="31" lly="-8" urx="539" ury="514"/>
<char name="guillemotleft" width="500" llx="23" lly="36" urx="473" ury="415"/>
<char name="guillemotright" width="500" llx="27" lly="36" urx="477" ury="415"/>
<char name="guilsinglleft" width="333" llx="51" lly="36" urx="305" ury="415"/>
<char name="guilsinglright" width="333" llx="28" lly="36" urx="282" ury="415"/>
<char name="h" width="556" llx="16" lly="0" urx="534" ury="676"/>
<char name="hungarumlaut" width="333" llx="-13" lly="528" urx="425" ury="713"/>
<char name="hyphen" width="333" llx="44" lly="171" urx="287" ury="287"/>
<char name="i" width="278" llx="16" lly="0" urx="255" ury="691"/>
<char name="iacute" width="278" llx="16" lly="0" urx="289" ury="713"/>
<char name="icircumflex" width="278" llx="-37" lly="0" urx="300" ury="704"/>
<char name="idieresis" width="278" llx="-37" lly="0" urx="300" ury="667"/>
<char name="igrave" width="278" llx="-27" lly="0" urx="255" ury="713"/>
<char name="j" width="333" llx="-57" lly="-203" urx="263" ury="691"/>
<char name="k" width="556" llx="22" lly="0" urx="543" ury="676"/>
<char name="l" width="278" llx="16" lly="0" urx="255" ury="676"/>
<char name="less" width="570" llx="31" lly="-8" urx="539" ury="514"/>
<char name="logicalnot" width="570" llx="33" lly="108" urx="537" ury="399"/>
<char name="lslash" width="278" llx="-22" lly="0" urx="303" ury="676"/>
<char name="m" width="833" llx="16" lly="0" urx="814" ury="473"/>
<char name="macron" width="333" llx="1" lly="565" urx="331" ury="637"/>
<char name="minus" width="324" llx="33" lly="209" urx="537" ury="297"/>
<char name="mu" width="556" llx="33" lly="-206" urx="536" ury="461"/>
<char name="multiply" width="570" llx="48" lly="16" urx="522" ury="490"/>
<char name="n" width="556" llx="21" lly="0" urx="539" ury="473"/>
<char name="nine" width="500" llx="26" lly="-13" urx="473" ury="688"/>
<char name="ntilde" width="556" llx="21" lly="0" urx="539" ury="674"/>
<char name="numbersign" width="500" llx="4" lly="0" urx="496" ury="700"/>
<char name="o" width="500" llx="25" lly="-14" urx="476" ury="473"/>
<char name="oacute" width="500" llx="25" lly="-14" urx="476" ury="713"/>
<char name="ocircumflex" width="500" llx="25" lly="-14" urx="476" ury="704"/>
<char name="odieresis" width="500" llx="25" lly="-14" urx="476" ury="667"/>
<char name="oe" width="722" llx="22" lly="-14" urx="696" ury="473"/>
<char name="ogonek" width="333" llx="90" lly="-193" urx="319" ury="24"/>
<char name="ograve" width="500" llx="25" lly="-14" urx="476" ury="713"/>
<char name="one" width="500" llx="65" lly="0" urx="442" ury="688"/>
<char name="onehalf" width="750" llx="-7" lly="-12" urx="775" ury="688"/>
<char name="onequarter" width="750" llx="28" lly="-12" urx="743" ury="688"/>
<char name="onesuperior" width="300" llx="28" lly="275" urx="273" ury="688"/>
<char name="ordfeminine" width="300" llx="-1" lly="397" urx="301" ury="688"/>
<char name="ordmasculine" width="330" llx="18" lly="397" urx="312" ury="688"/>
<char name="oslash" width="500" llx="25" lly="-92" urx="476" ury="549"/>
<char name="otilde" width="500" llx="25" lly="-14" urx="476" ury="674"/>
<char name="p" width="556" llx="19" lly="-205" urx="524" ury="473"/>
<char name="paragraph" width="540" llx="0" lly="-186" urx="519" ury="676"/>
<char name="parenleft" width="333" llx="46" lly="-168" urx="306" ury="694"/>
<char name="parenright" width="333" llx="27" lly="-168" urx="287" ury="694"/>
<char name="percent" width="1000" llx="124" lly="-14" urx="877" ury="692"/>
<char name="period" width="250" llx="41" lly="-13" urx="210" ury="156"/>
<char name="periodcentered" width="250" llx="41" lly="248" urx="210" ury="417"/>
<char name="perthousand" width="1000" llx="7" lly="-29" urx="995" ury="706"/>
<char name="plus" width="570" llx="33" lly="0" urx="537" ury="506"/>
<char name="plusminus" width="570" llx="33" lly="0" urx="537" ury="506"/>
<char name="q" width="556" llx="34" lly="-205" urx="536" ury="473"/>
<char name="question" width="500" llx="57" lly="-13" urx="445" ury="689"/>
<char name="questiondown" width="500" llx="55" lly="-201" urx="443" ury="501"/>
<char name="quotedbl" width="555" llx="83" lly="404" urx="472" ury="691"/>
<char name="quotedblbase" width="500" llx="14" lly="-180" urx="468" ury="155"/>
<char name="quotedblleft" width="500" llx="32" lly="356" urx="486" ury="691"/>
<char name="quotedblright" width="500" llx="14" lly="356" urx="468" ury="691"/>
<char name="quoteleft" width="333" llx="70" lly="356" urx="254" ury="691"/>
<char name="quoteright" width="333" llx="79" lly="356" urx="263" ury="691"/>
<char name="quotesinglbase" width="333" llx="79" lly="-180" urx="263" ury="155"/>
<char name="quotesingle" width="278" llx="75" lly="404" urx="204" ury="691"/>
<char name="r" width="444" llx="29" lly="0" urx="434" ury="473"/>
<char name="registered" width="747" llx="26" lly="-19" urx="721" ury="691"/>
<char name="ring" width="333" llx="60" lly="527" urx="273" ury="740"/>
<char name="s" width="389" llx="25" lly="-14" urx="361" ury="473"/>
<char name="scaron" width="389" llx="25" lly="-14" urx="363" ury="704"/>
<char name="section" width="500" llx="57" lly="-132" urx="443" ury="691"/>
<char name="semicolon" width="333" llx="82" lly="-180" urx="266" ury="472"/>
<char name="seven" width="500" llx="17" lly="0" urx="477" ury="676"/>
<char name="six" width="500" llx="28" lly="-13" urx="475" ury="688"/>
<char name="slash" width="278" llx="-24" lly="-19" urx="302" ury="691"/>
<char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="250"/>
<char name="sterling" width="500"/>
<char name="t" width="333"/>
<char name="thorn" width="556"/>
<char name="three" width="500"/>
<char name="threequarters" width="750"/>
<char name="threesuperior" width="300"/>
<char name="tilde" width="333"/>
<char name="trademark" width="1000"/>
<char name="two" width="500"/>
<char name="twosuperior" width="300"/>
<char name="u" width="556"/>
<char name="uacute" width="556"/>
<char name="ucircumflex" width="556"/>
<char name="udieresis" width="556"/>
<char name="ugrave" width="556"/>
<char name="underscore" width="500"/>
<char name="v" width="500"/>
<char name="w" width="722"/>
<char name="x" width="500"/>
<char name="y" width="500"/>
<char name="yacute" width="500"/>
<char name="ydieresis" width="500"/>
<char name="yen" width="500"/>
<char name="z" width="444"/>
<char name="zcaron" width="444"/>
<char name="zero" width="500"/>
</widths>
<char name="sterling" width="500" llx="21" lly="-14" urx="477" ury="684"/>
<char name="t" width="333" llx="20" lly="-12" urx="332" ury="630"/>
<char name="thorn" width="556" llx="19" lly="-205" urx="524" ury="676"/>
<char name="three" width="500" llx="16" lly="-14" urx="468" ury="688"/>
<char name="threequarters" width="750" llx="23" lly="-12" urx="733" ury="688"/>
<char name="threesuperior" width="300" llx="3" lly="268" urx="297" ury="688"/>
<char name="tilde" width="333" llx="-16" lly="547" urx="349" ury="674"/>
<char name="trademark" width="1000" llx="24" lly="271" urx="977" ury="676"/>
<char name="two" width="500" llx="17" lly="0" urx="478" ury="688"/>
<char name="twosuperior" width="300" llx="0" lly="275" urx="300" ury="688"/>
<char name="u" width="556" llx="16" lly="-14" urx="537" ury="461"/>
<char name="uacute" width="556" llx="16" lly="-14" urx="537" ury="713"/>
<char name="ucircumflex" width="556" llx="16" lly="-14" urx="537" ury="704"/>
<char name="udieresis" width="556" llx="16" lly="-14" urx="537" ury="667"/>
<char name="ugrave" width="556" llx="16" lly="-14" urx="537" ury="713"/>
<char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/>
<char name="v" width="500" llx="21" lly="-14" urx="485" ury="461"/>
<char name="w" width="722" llx="23" lly="-14" urx="707" ury="461"/>
<char name="x" width="500" llx="12" lly="0" urx="484" ury="461"/>
<char name="y" width="500" llx="16" lly="-205" urx="480" ury="461"/>
<char name="yacute" width="500" llx="16" lly="-205" urx="480" ury="713"/>
<char name="ydieresis" width="500" llx="16" lly="-205" urx="480" ury="667"/>
<char name="yen" width="500" llx="-64" lly="0" urx="547" ury="676"/>
<char name="z" width="444" llx="21" lly="0" urx="420" ury="461"/>
<char name="zcaron" width="444" llx="21" lly="0" urx="420" ury="704"/>
<char name="zero" width="500" llx="24" lly="-13" urx="476" ury="688"/>
</char-metrics>
<kerning kpx1="79">
<pair kern="-40" kpx2="65"/>
<pair kern="-50" kpx2="87"/>

+ 233
- 232
src/codegen/fonts/TimesBoldItalic.xml View File

@@ -22,245 +22,246 @@
<family-name>Times</family-name>
<class-name>TimesBoldItalic</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>669</cap-height>
<x-height>462</x-height>
<ascender>699</ascender>
<descender>-205</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="667"/>
<char name="AE" width="944"/>
<char name="Aacute" width="667"/>
<char name="Acircumflex" width="667"/>
<char name="Adieresis" width="667"/>
<char name="Agrave" width="667"/>
<char name="Aring" width="667"/>
<char name="Atilde" width="667"/>
<char name="B" width="667"/>
<char name="C" width="667"/>
<char name="Ccedilla" width="667"/>
<char name="D" width="722"/>
<char name="E" width="667"/>
<char name="Eacute" width="667"/>
<char name="Ecircumflex" width="667"/>
<char name="Edieresis" width="667"/>
<char name="Egrave" width="667"/>
<char name="Eth" width="722"/>
<char name="Euro" width="500"/>
<char name="F" width="667"/>
<char name="G" width="722"/>
<char name="H" width="778"/>
<char name="I" width="389"/>
<char name="Iacute" width="389"/>
<char name="Icircumflex" width="389"/>
<char name="Idieresis" width="389"/>
<char name="Igrave" width="389"/>
<char name="J" width="500"/>
<char name="K" width="667"/>
<char name="L" width="611"/>
<char name="Lslash" width="611"/>
<char name="M" width="889"/>
<char name="N" width="722"/>
<char name="Ntilde" width="722"/>
<char name="O" width="722"/>
<char name="OE" width="944"/>
<char name="Oacute" width="722"/>
<char name="Ocircumflex" width="722"/>
<char name="Odieresis" width="722"/>
<char name="Ograve" width="722"/>
<char name="Oslash" width="722"/>
<char name="Otilde" width="722"/>
<char name="P" width="611"/>
<char name="Q" width="722"/>
<char name="R" width="667"/>
<char name="S" width="556"/>
<char name="Scaron" width="556"/>
<char name="T" width="611"/>
<char name="Thorn" width="611"/>
<char name="U" width="722"/>
<char name="Uacute" width="722"/>
<char name="Ucircumflex" width="722"/>
<char name="Udieresis" width="722"/>
<char name="Ugrave" width="722"/>
<char name="V" width="667"/>
<char name="W" width="889"/>
<char name="X" width="667"/>
<char name="Y" width="611"/>
<char name="Yacute" width="611"/>
<char name="Ydieresis" width="611"/>
<char name="Z" width="611"/>
<char name="Zcaron" width="611"/>
<char name="a" width="500"/>
<char name="aacute" width="500"/>
<char name="acircumflex" width="500"/>
<char name="acute" width="333"/>
<char name="adieresis" width="500"/>
<char name="ae" width="722"/>
<char name="agrave" width="500"/>
<char name="ampersand" width="778"/>
<char name="aring" width="500"/>
<char name="asciicircum" width="570"/>
<char name="asciitilde" width="570"/>
<char name="asterisk" width="500"/>
<char name="at" width="832"/>
<char name="atilde" width="500"/>
<char name="b" width="500"/>
<char name="backslash" width="278"/>
<char name="bar" width="220"/>
<char name="braceleft" width="348"/>
<char name="braceright" width="348"/>
<char name="bracketleft" width="333"/>
<char name="bracketright" width="333"/>
<char name="breve" width="333"/>
<char name="brokenbar" width="220"/>
<char name="bullet" width="350"/>
<char name="c" width="444"/>
<char name="caron" width="333"/>
<char name="ccedilla" width="444"/>
<char name="cedilla" width="333"/>
<char name="cent" width="500"/>
<char name="circumflex" width="333"/>
<char name="colon" width="333"/>
<char name="comma" width="250"/>
<char name="copyright" width="747"/>
<char name="currency" width="500"/>
<char name="d" width="500"/>
<char name="dagger" width="500"/>
<char name="daggerdbl" width="500"/>
<char name="degree" width="400"/>
<char name="dieresis" width="333"/>
<char name="divide" width="570"/>
<char name="dollar" width="500"/>
<char name="dotaccent" width="333"/>
<char name="dotlessi" width="278"/>
<char name="e" width="444"/>
<char name="eacute" width="444"/>
<char name="ecircumflex" width="444"/>
<char name="edieresis" width="444"/>
<char name="egrave" width="444"/>
<char name="eight" width="500"/>
<char name="ellipsis" width="1000"/>
<char name="emdash" width="1000"/>
<char name="endash" width="500"/>
<char name="equal" width="570"/>
<char name="eth" width="500"/>
<char name="exclam" width="389"/>
<char name="exclamdown" width="389"/>
<char name="f" width="333"/>
<char name="fi" width="556"/>
<char name="five" width="500"/>
<char name="fl" width="556"/>
<char name="florin" width="500"/>
<char name="four" width="500"/>
<char name="fraction" width="167"/>
<char name="g" width="500"/>
<char name="germandbls" width="500"/>
<char name="grave" width="333"/>
<char name="greater" width="570"/>
<char name="guillemotleft" width="500"/>
<char name="guillemotright" width="500"/>
<char name="guilsinglleft" width="333"/>
<char name="guilsinglright" width="333"/>
<char name="h" width="556"/>
<char name="hungarumlaut" width="333"/>
<char name="hyphen" width="333"/>
<char name="i" width="278"/>
<char name="iacute" width="278"/>
<char name="icircumflex" width="278"/>
<char name="idieresis" width="278"/>
<char name="igrave" width="278"/>
<char name="j" width="278"/>
<char name="k" width="500"/>
<char name="l" width="278"/>
<char name="less" width="570"/>
<char name="logicalnot" width="606"/>
<char name="lslash" width="278"/>
<char name="m" width="778"/>
<char name="macron" width="333"/>
<char name="minus" width="330"/>
<char name="mu" width="576"/>
<char name="multiply" width="570"/>
<char name="n" width="556"/>
<char name="nine" width="500"/>
<char name="ntilde" width="556"/>
<char name="numbersign" width="500"/>
<char name="o" width="500"/>
<char name="oacute" width="500"/>
<char name="ocircumflex" width="500"/>
<char name="odieresis" width="500"/>
<char name="oe" width="722"/>
<char name="ogonek" width="333"/>
<char name="ograve" width="500"/>
<char name="one" width="500"/>
<char name="onehalf" width="750"/>
<char name="onequarter" width="750"/>
<char name="onesuperior" width="300"/>
<char name="ordfeminine" width="266"/>
<char name="ordmasculine" width="300"/>
<char name="oslash" width="500"/>
<char name="otilde" width="500"/>
<char name="p" width="500"/>
<char name="paragraph" width="500"/>
<char name="parenleft" width="333"/>
<char name="parenright" width="333"/>
<char name="percent" width="833"/>
<char name="period" width="250"/>
<char name="periodcentered" width="250"/>
<char name="perthousand" width="1000"/>
<char name="plus" width="570"/>
<char name="plusminus" width="570"/>
<char name="q" width="500"/>
<char name="question" width="500"/>
<char name="questiondown" width="500"/>
<char name="quotedbl" width="555"/>
<char name="quotedblbase" width="500"/>
<char name="quotedblleft" width="500"/>
<char name="quotedblright" width="500"/>
<char name="quoteleft" width="333"/>
<char name="quoteright" width="333"/>
<char name="quotesinglbase" width="333"/>
<char name="quotesingle" width="278"/>
<char name="r" width="389"/>
<char name="registered" width="747"/>
<char name="ring" width="333"/>
<char name="s" width="389"/>
<char name="scaron" width="389"/>
<char name="section" width="500"/>
<char name="semicolon" width="333"/>
<char name="seven" width="500"/>
<char name="six" width="500"/>
<char name="slash" width="278"/>
<char name="space" width="250"/>
<char-metrics>
<char name="A" width="667" llx="-67" lly="0" urx="593" ury="683"/>
<char name="AE" width="944" llx="-64" lly="0" urx="918" ury="669"/>
<char name="Aacute" width="667" llx="-67" lly="0" urx="593" ury="904"/>
<char name="Acircumflex" width="667" llx="-67" lly="0" urx="593" ury="897"/>
<char name="Adieresis" width="667" llx="-67" lly="0" urx="593" ury="862"/>
<char name="Agrave" width="667" llx="-67" lly="0" urx="593" ury="904"/>
<char name="Aring" width="667" llx="-67" lly="0" urx="593" ury="921"/>
<char name="Atilde" width="667" llx="-67" lly="0" urx="593" ury="862"/>
<char name="B" width="667" llx="-24" lly="0" urx="624" ury="669"/>
<char name="C" width="667" llx="32" lly="-18" urx="677" ury="685"/>
<char name="Ccedilla" width="667" llx="32" lly="-218" urx="677" ury="685"/>
<char name="D" width="722" llx="-46" lly="0" urx="685" ury="669"/>
<char name="E" width="667" llx="-27" lly="0" urx="653" ury="669"/>
<char name="Eacute" width="667" llx="-27" lly="0" urx="653" ury="904"/>
<char name="Ecircumflex" width="667" llx="-27" lly="0" urx="653" ury="897"/>
<char name="Edieresis" width="667" llx="-27" lly="0" urx="653" ury="862"/>
<char name="Egrave" width="667" llx="-27" lly="0" urx="653" ury="904"/>
<char name="Eth" width="722" llx="-31" lly="0" urx="700" ury="669"/>
<char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="667" llx="-13" lly="0" urx="660" ury="669"/>
<char name="G" width="722" llx="21" lly="-18" urx="706" ury="685"/>
<char name="H" width="778" llx="-24" lly="0" urx="799" ury="669"/>
<char name="I" width="389" llx="-32" lly="0" urx="406" ury="669"/>
<char name="Iacute" width="389" llx="-32" lly="0" urx="432" ury="904"/>
<char name="Icircumflex" width="389" llx="-32" lly="0" urx="450" ury="897"/>
<char name="Idieresis" width="389" llx="-32" lly="0" urx="450" ury="862"/>
<char name="Igrave" width="389" llx="-32" lly="0" urx="406" ury="904"/>
<char name="J" width="500" llx="-46" lly="-99" urx="524" ury="669"/>
<char name="K" width="667" llx="-21" lly="0" urx="702" ury="669"/>
<char name="L" width="611" llx="-22" lly="0" urx="590" ury="669"/>
<char name="Lslash" width="611" llx="-22" lly="0" urx="590" ury="669"/>
<char name="M" width="889" llx="-29" lly="-12" urx="917" ury="669"/>
<char name="N" width="722" llx="-27" lly="-15" urx="748" ury="669"/>
<char name="Ntilde" width="722" llx="-27" lly="-15" urx="748" ury="862"/>
<char name="O" width="722" llx="27" lly="-18" urx="691" ury="685"/>
<char name="OE" width="944" llx="23" lly="-8" urx="946" ury="677"/>
<char name="Oacute" width="722" llx="27" lly="-18" urx="691" ury="904"/>
<char name="Ocircumflex" width="722" llx="27" lly="-18" urx="691" ury="897"/>
<char name="Odieresis" width="722" llx="27" lly="-18" urx="691" ury="862"/>
<char name="Ograve" width="722" llx="27" lly="-18" urx="691" ury="904"/>
<char name="Oslash" width="722" llx="27" lly="-125" urx="691" ury="764"/>
<char name="Otilde" width="722" llx="27" lly="-18" urx="691" ury="862"/>
<char name="P" width="611" llx="-27" lly="0" urx="613" ury="669"/>
<char name="Q" width="722" llx="27" lly="-208" urx="691" ury="685"/>
<char name="R" width="667" llx="-29" lly="0" urx="623" ury="669"/>
<char name="S" width="556" llx="2" lly="-18" urx="526" ury="685"/>
<char name="Scaron" width="556" llx="2" lly="-18" urx="553" ury="897"/>
<char name="T" width="611" llx="50" lly="0" urx="650" ury="669"/>
<char name="Thorn" width="611" llx="-27" lly="0" urx="573" ury="669"/>
<char name="U" width="722" llx="67" lly="-18" urx="744" ury="669"/>
<char name="Uacute" width="722" llx="67" lly="-18" urx="744" ury="904"/>
<char name="Ucircumflex" width="722" llx="67" lly="-18" urx="744" ury="897"/>
<char name="Udieresis" width="722" llx="67" lly="-18" urx="744" ury="862"/>
<char name="Ugrave" width="722" llx="67" lly="-18" urx="744" ury="904"/>
<char name="V" width="667" llx="65" lly="-18" urx="715" ury="669"/>
<char name="W" width="889" llx="65" lly="-18" urx="940" ury="669"/>
<char name="X" width="667" llx="-24" lly="0" urx="694" ury="669"/>
<char name="Y" width="611" llx="73" lly="0" urx="659" ury="669"/>
<char name="Yacute" width="611" llx="73" lly="0" urx="659" ury="904"/>
<char name="Ydieresis" width="611" llx="73" lly="0" urx="659" ury="862"/>
<char name="Z" width="611" llx="-11" lly="0" urx="590" ury="669"/>
<char name="Zcaron" width="611" llx="-11" lly="0" urx="590" ury="897"/>
<char name="a" width="500" llx="-21" lly="-14" urx="455" ury="462"/>
<char name="aacute" width="500" llx="-21" lly="-14" urx="463" ury="697"/>
<char name="acircumflex" width="500" llx="-21" lly="-14" urx="455" ury="690"/>
<char name="acute" width="333" llx="139" lly="516" urx="379" ury="697"/>
<char name="adieresis" width="500" llx="-21" lly="-14" urx="476" ury="655"/>
<char name="ae" width="722" llx="-5" lly="-13" urx="673" ury="462"/>
<char name="agrave" width="500" llx="-21" lly="-14" urx="455" ury="697"/>
<char name="ampersand" width="778" llx="5" lly="-19" urx="699" ury="682"/>
<char name="aring" width="500" llx="-21" lly="-14" urx="455" ury="729"/>
<char name="asciicircum" width="570" llx="67" lly="304" urx="503" ury="669"/>
<char name="asciitilde" width="570" llx="54" lly="173" urx="516" ury="333"/>
<char name="asterisk" width="500" llx="65" lly="249" urx="456" ury="685"/>
<char name="at" width="832" llx="63" lly="-18" urx="770" ury="685"/>
<char name="atilde" width="500" llx="-21" lly="-14" urx="491" ury="655"/>
<char name="b" width="500" llx="-14" lly="-13" urx="444" ury="699"/>
<char name="backslash" width="278" llx="-1" lly="-18" urx="279" ury="685"/>
<char name="bar" width="220" llx="66" lly="-218" urx="154" ury="782"/>
<char name="braceleft" width="348" llx="5" lly="-187" urx="436" ury="686"/>
<char name="braceright" width="348" llx="-129" lly="-187" urx="302" ury="686"/>
<char name="bracketleft" width="333" llx="-37" lly="-159" urx="362" ury="674"/>
<char name="bracketright" width="333" llx="-56" lly="-157" urx="343" ury="674"/>
<char name="breve" width="333" llx="71" lly="516" urx="387" ury="678"/>
<char name="brokenbar" width="220" llx="66" lly="-143" urx="154" ury="707"/>
<char name="bullet" width="350" llx="0" lly="175" urx="350" ury="525"/>
<char name="c" width="444" llx="-5" lly="-13" urx="392" ury="462"/>
<char name="caron" width="333" llx="79" lly="516" urx="411" ury="690"/>
<char name="ccedilla" width="444" llx="-5" lly="-218" urx="392" ury="462"/>
<char name="cedilla" width="333" llx="-80" lly="-218" urx="156" ury="5"/>
<char name="cent" width="500" llx="42" lly="-143" urx="439" ury="576"/>
<char name="circumflex" width="333" llx="40" lly="516" urx="367" ury="690"/>
<char name="colon" width="333" llx="23" lly="-13" urx="264" ury="459"/>
<char name="comma" width="250" llx="-60" lly="-182" urx="144" ury="134"/>
<char name="copyright" width="747" llx="30" lly="-18" urx="718" ury="685"/>
<char name="currency" width="500" llx="-26" lly="34" urx="526" ury="586"/>
<char name="d" width="500" llx="-21" lly="-13" urx="517" ury="699"/>
<char name="dagger" width="500" llx="91" lly="-145" urx="494" ury="685"/>
<char name="daggerdbl" width="500" llx="10" lly="-139" urx="493" ury="685"/>
<char name="degree" width="400" llx="83" lly="397" urx="369" ury="683"/>
<char name="dieresis" width="333" llx="55" lly="550" urx="402" ury="684"/>
<char name="divide" width="570" llx="33" lly="-29" urx="537" ury="535"/>
<char name="dollar" width="500" llx="-20" lly="-100" urx="497" ury="733"/>
<char name="dotaccent" width="333" llx="163" lly="550" urx="298" ury="684"/>
<char name="dotlessi" width="278" llx="2" lly="-9" urx="238" ury="462"/>
<char name="e" width="444" llx="5" lly="-13" urx="398" ury="462"/>
<char name="eacute" width="444" llx="5" lly="-13" urx="435" ury="697"/>
<char name="ecircumflex" width="444" llx="5" lly="-13" urx="423" ury="690"/>
<char name="edieresis" width="444" llx="5" lly="-13" urx="448" ury="655"/>
<char name="egrave" width="444" llx="5" lly="-13" urx="398" ury="697"/>
<char name="eight" width="500" llx="3" lly="-13" urx="476" ury="683"/>
<char name="ellipsis" width="1000" llx="40" lly="-13" urx="852" ury="135"/>
<char name="emdash" width="1000" llx="-40" lly="178" urx="977" ury="269"/>
<char name="endash" width="500" llx="-40" lly="178" urx="477" ury="269"/>
<char name="equal" width="570" llx="33" lly="107" urx="537" ury="399"/>
<char name="eth" width="500" llx="-3" lly="-13" urx="454" ury="699"/>
<char name="exclam" width="389" llx="67" lly="-13" urx="370" ury="684"/>
<char name="exclamdown" width="389" llx="19" lly="-205" urx="322" ury="492"/>
<char name="f" width="333" llx="-169" lly="-205" urx="446" ury="698"/>
<char name="fi" width="556" llx="-188" lly="-205" urx="514" ury="703"/>
<char name="five" width="500" llx="-11" lly="-13" urx="487" ury="669"/>
<char name="fl" width="556" llx="-186" lly="-205" urx="553" ury="704"/>
<char name="florin" width="500" llx="-87" lly="-156" urx="537" ury="707"/>
<char name="four" width="500" llx="-15" lly="0" urx="503" ury="683"/>
<char name="fraction" width="167" llx="-169" lly="-14" urx="324" ury="683"/>
<char name="g" width="500" llx="-52" lly="-203" urx="478" ury="462"/>
<char name="germandbls" width="500" llx="-200" lly="-200" urx="473" ury="705"/>
<char name="grave" width="333" llx="85" lly="516" urx="297" ury="697"/>
<char name="greater" width="570" llx="31" lly="-8" urx="539" ury="514"/>
<char name="guillemotleft" width="500" llx="12" lly="32" urx="468" ury="415"/>
<char name="guillemotright" width="500" llx="12" lly="32" urx="468" ury="415"/>
<char name="guilsinglleft" width="333" llx="32" lly="32" urx="303" ury="415"/>
<char name="guilsinglright" width="333" llx="10" lly="32" urx="281" ury="415"/>
<char name="h" width="556" llx="-13" lly="-9" urx="498" ury="699"/>
<char name="hungarumlaut" width="333" llx="69" lly="516" urx="498" ury="697"/>
<char name="hyphen" width="333" llx="2" lly="166" urx="271" ury="282"/>
<char name="i" width="278" llx="2" lly="-9" urx="263" ury="684"/>
<char name="iacute" width="278" llx="2" lly="-9" urx="352" ury="697"/>
<char name="icircumflex" width="278" llx="-3" lly="-9" urx="324" ury="690"/>
<char name="idieresis" width="278" llx="2" lly="-9" urx="364" ury="655"/>
<char name="igrave" width="278" llx="2" lly="-9" urx="259" ury="697"/>
<char name="j" width="278" llx="-189" lly="-207" urx="279" ury="684"/>
<char name="k" width="500" llx="-23" lly="-8" urx="483" ury="699"/>
<char name="l" width="278" llx="2" lly="-9" urx="290" ury="699"/>
<char name="less" width="570" llx="31" lly="-8" urx="539" ury="514"/>
<char name="logicalnot" width="606" llx="51" lly="108" urx="555" ury="399"/>
<char name="lslash" width="278" llx="-7" lly="-9" urx="307" ury="699"/>
<char name="m" width="778" llx="-14" lly="-9" urx="722" ury="462"/>
<char name="macron" width="333" llx="51" lly="553" urx="393" ury="623"/>
<char name="minus" width="330" llx="51" lly="209" urx="555" ury="297"/>
<char name="mu" width="576" llx="-60" lly="-207" urx="516" ury="449"/>
<char name="multiply" width="570" llx="48" lly="16" urx="522" ury="490"/>
<char name="n" width="556" llx="-6" lly="-9" urx="493" ury="462"/>
<char name="nine" width="500" llx="-12" lly="-10" urx="475" ury="683"/>
<char name="ntilde" width="556" llx="-6" lly="-9" urx="504" ury="655"/>
<char name="numbersign" width="500" llx="-33" lly="0" urx="533" ury="700"/>
<char name="o" width="500" llx="-3" lly="-13" urx="441" ury="462"/>
<char name="oacute" width="500" llx="-3" lly="-13" urx="463" ury="697"/>
<char name="ocircumflex" width="500" llx="-3" lly="-13" urx="451" ury="690"/>
<char name="odieresis" width="500" llx="-3" lly="-13" urx="471" ury="655"/>
<char name="oe" width="722" llx="6" lly="-13" urx="674" ury="462"/>
<char name="ogonek" width="333" llx="15" lly="-183" urx="244" ury="34"/>
<char name="ograve" width="500" llx="-3" lly="-13" urx="441" ury="697"/>
<char name="one" width="500" llx="5" lly="0" urx="419" ury="683"/>
<char name="onehalf" width="750" llx="-9" lly="-14" urx="723" ury="683"/>
<char name="onequarter" width="750" llx="7" lly="-14" urx="721" ury="683"/>
<char name="onesuperior" width="300" llx="30" lly="274" urx="301" ury="683"/>
<char name="ordfeminine" width="266" llx="16" lly="399" urx="330" ury="685"/>
<char name="ordmasculine" width="300" llx="56" lly="400" urx="347" ury="685"/>
<char name="oslash" width="500" llx="-3" lly="-119" urx="441" ury="560"/>
<char name="otilde" width="500" llx="-3" lly="-13" urx="491" ury="655"/>
<char name="p" width="500" llx="-120" lly="-205" urx="446" ury="462"/>
<char name="paragraph" width="500" llx="-57" lly="-193" urx="562" ury="669"/>
<char name="parenleft" width="333" llx="28" lly="-179" urx="344" ury="685"/>
<char name="parenright" width="333" llx="-44" lly="-179" urx="271" ury="685"/>
<char name="percent" width="833" llx="39" lly="-10" urx="793" ury="692"/>
<char name="period" width="250" llx="-9" lly="-13" urx="139" ury="135"/>
<char name="periodcentered" width="250" llx="51" lly="257" urx="199" ury="405"/>
<char name="perthousand" width="1000" llx="7" lly="-29" urx="996" ury="706"/>
<char name="plus" width="570" llx="33" lly="0" urx="537" ury="506"/>
<char name="plusminus" width="570" llx="33" lly="0" urx="537" ury="506"/>
<char name="q" width="500" llx="1" lly="-205" urx="471" ury="462"/>
<char name="question" width="500" llx="79" lly="-13" urx="470" ury="684"/>
<char name="questiondown" width="500" llx="30" lly="-205" urx="421" ury="492"/>
<char name="quotedbl" width="555" llx="136" lly="398" urx="536" ury="685"/>
<char name="quotedblbase" width="500" llx="-57" lly="-182" urx="403" ury="134"/>
<char name="quotedblleft" width="500" llx="53" lly="369" urx="513" ury="685"/>
<char name="quotedblright" width="500" llx="53" lly="369" urx="513" ury="685"/>
<char name="quoteleft" width="333" llx="128" lly="369" urx="332" ury="685"/>
<char name="quoteright" width="333" llx="98" lly="369" urx="302" ury="685"/>
<char name="quotesinglbase" width="333" llx="-5" lly="-182" urx="199" ury="134"/>
<char name="quotesingle" width="278" llx="128" lly="398" urx="268" ury="685"/>
<char name="r" width="389" llx="-21" lly="0" urx="389" ury="462"/>
<char name="registered" width="747" llx="30" lly="-18" urx="718" ury="685"/>
<char name="ring" width="333" llx="127" lly="516" urx="340" ury="729"/>
<char name="s" width="389" llx="-19" lly="-13" urx="333" ury="462"/>
<char name="scaron" width="389" llx="-19" lly="-13" urx="424" ury="690"/>
<char name="section" width="500" llx="36" lly="-143" urx="459" ury="685"/>
<char name="semicolon" width="333" llx="-25" lly="-183" urx="264" ury="459"/>
<char name="seven" width="500" llx="52" lly="0" urx="525" ury="669"/>
<char name="six" width="500" llx="23" lly="-15" urx="509" ury="679"/>
<char name="slash" width="278" llx="-64" lly="-18" urx="342" ury="685"/>
<char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="250"/>
<char name="sterling" width="500"/>
<char name="t" width="278"/>
<char name="thorn" width="500"/>
<char name="three" width="500"/>
<char name="threequarters" width="750"/>
<char name="threesuperior" width="300"/>
<char name="tilde" width="333"/>
<char name="trademark" width="1000"/>
<char name="two" width="500"/>
<char name="twosuperior" width="300"/>
<char name="u" width="556"/>
<char name="uacute" width="556"/>
<char name="ucircumflex" width="556"/>
<char name="udieresis" width="556"/>
<char name="ugrave" width="556"/>
<char name="underscore" width="500"/>
<char name="v" width="444"/>
<char name="w" width="667"/>
<char name="x" width="500"/>
<char name="y" width="444"/>
<char name="yacute" width="444"/>
<char name="ydieresis" width="444"/>
<char name="yen" width="500"/>
<char name="z" width="389"/>
<char name="zcaron" width="389"/>
<char name="zero" width="500"/>
</widths>
<char name="sterling" width="500" llx="-32" lly="-12" urx="510" ury="683"/>
<char name="t" width="278" llx="-11" lly="-9" urx="281" ury="594"/>
<char name="thorn" width="500" llx="-120" lly="-205" urx="446" ury="699"/>
<char name="three" width="500" llx="-15" lly="-13" urx="450" ury="683"/>
<char name="threequarters" width="750" llx="7" lly="-14" urx="726" ury="683"/>
<char name="threesuperior" width="300" llx="17" lly="265" urx="321" ury="683"/>
<char name="tilde" width="333" llx="48" lly="536" urx="407" ury="655"/>
<char name="trademark" width="1000" llx="32" lly="263" urx="968" ury="669"/>
<char name="two" width="500" llx="-27" lly="0" urx="446" ury="683"/>
<char name="twosuperior" width="300" llx="2" lly="274" urx="313" ury="683"/>
<char name="u" width="556" llx="15" lly="-9" urx="492" ury="462"/>
<char name="uacute" width="556" llx="15" lly="-9" urx="492" ury="697"/>
<char name="ucircumflex" width="556" llx="15" lly="-9" urx="492" ury="690"/>
<char name="udieresis" width="556" llx="15" lly="-9" urx="499" ury="655"/>
<char name="ugrave" width="556" llx="15" lly="-9" urx="492" ury="697"/>
<char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/>
<char name="v" width="444" llx="16" lly="-13" urx="401" ury="462"/>
<char name="w" width="667" llx="16" lly="-13" urx="614" ury="462"/>
<char name="x" width="500" llx="-46" lly="-13" urx="469" ury="462"/>
<char name="y" width="444" llx="-94" lly="-205" urx="392" ury="462"/>
<char name="yacute" width="444" llx="-94" lly="-205" urx="435" ury="697"/>
<char name="ydieresis" width="444" llx="-94" lly="-205" urx="443" ury="655"/>
<char name="yen" width="500" llx="33" lly="0" urx="628" ury="669"/>
<char name="z" width="389" llx="-43" lly="-78" urx="368" ury="449"/>
<char name="zcaron" width="389" llx="-43" lly="-78" urx="424" ury="690"/>
<char name="zero" width="500" llx="17" lly="-14" urx="477" ury="683"/>
</char-metrics>
<kerning kpx1="79">
<pair kern="-40" kpx2="65"/>
<pair kern="-50" kpx2="87"/>

+ 234
- 233
src/codegen/fonts/TimesItalic.xml View File

@@ -22,245 +22,246 @@
<family-name>Times</family-name>
<class-name>TimesItalic</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>653</cap-height>
<x-height>441</x-height>
<ascender>683</ascender>
<descender>-205</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="611"/>
<char name="AE" width="889"/>
<char name="Aacute" width="611"/>
<char name="Acircumflex" width="611"/>
<char name="Adieresis" width="611"/>
<char name="Agrave" width="611"/>
<char name="Aring" width="611"/>
<char name="Atilde" width="611"/>
<char name="B" width="611"/>
<char name="C" width="667"/>
<char name="Ccedilla" width="667"/>
<char name="D" width="722"/>
<char name="E" width="611"/>
<char name="Eacute" width="611"/>
<char name="Ecircumflex" width="611"/>
<char name="Edieresis" width="611"/>
<char name="Egrave" width="611"/>
<char name="Eth" width="722"/>
<char name="Euro" width="500"/>
<char name="F" width="611"/>
<char name="G" width="722"/>
<char name="H" width="722"/>
<char name="I" width="333"/>
<char name="Iacute" width="333"/>
<char name="Icircumflex" width="333"/>
<char name="Idieresis" width="333"/>
<char name="Igrave" width="333"/>
<char name="J" width="444"/>
<char name="K" width="667"/>
<char name="L" width="556"/>
<char name="Lslash" width="556"/>
<char name="M" width="833"/>
<char name="N" width="667"/>
<char name="Ntilde" width="667"/>
<char name="O" width="722"/>
<char name="OE" width="944"/>
<char name="Oacute" width="722"/>
<char name="Ocircumflex" width="722"/>
<char name="Odieresis" width="722"/>
<char name="Ograve" width="722"/>
<char name="Oslash" width="722"/>
<char name="Otilde" width="722"/>
<char name="P" width="611"/>
<char name="Q" width="722"/>
<char name="R" width="611"/>
<char name="S" width="500"/>
<char name="Scaron" width="500"/>
<char name="T" width="556"/>
<char name="Thorn" width="611"/>
<char name="U" width="722"/>
<char name="Uacute" width="722"/>
<char name="Ucircumflex" width="722"/>
<char name="Udieresis" width="722"/>
<char name="Ugrave" width="722"/>
<char name="V" width="611"/>
<char name="W" width="833"/>
<char name="X" width="611"/>
<char name="Y" width="556"/>
<char name="Yacute" width="556"/>
<char name="Ydieresis" width="556"/>
<char name="Z" width="556"/>
<char name="Zcaron" width="556"/>
<char name="a" width="500"/>
<char name="aacute" width="500"/>
<char name="acircumflex" width="500"/>
<char name="acute" width="333"/>
<char name="adieresis" width="500"/>
<char name="ae" width="667"/>
<char name="agrave" width="500"/>
<char name="ampersand" width="778"/>
<char name="aring" width="500"/>
<char name="asciicircum" width="422"/>
<char name="asciitilde" width="541"/>
<char name="asterisk" width="500"/>
<char name="at" width="920"/>
<char name="atilde" width="500"/>
<char name="b" width="500"/>
<char name="backslash" width="278"/>
<char name="bar" width="275"/>
<char name="braceleft" width="400"/>
<char name="braceright" width="400"/>
<char name="bracketleft" width="389"/>
<char name="bracketright" width="389"/>
<char name="breve" width="333"/>
<char name="brokenbar" width="275"/>
<char name="bullet" width="350"/>
<char name="c" width="444"/>
<char name="caron" width="333"/>
<char name="ccedilla" width="444"/>
<char name="cedilla" width="333"/>
<char name="cent" width="500"/>
<char name="circumflex" width="333"/>
<char name="colon" width="333"/>
<char name="comma" width="250"/>
<char name="copyright" width="760"/>
<char name="currency" width="500"/>
<char name="d" width="500"/>
<char name="dagger" width="500"/>
<char name="daggerdbl" width="500"/>
<char name="degree" width="400"/>
<char name="dieresis" width="333"/>
<char name="divide" width="675"/>
<char name="dollar" width="500"/>
<char name="dotaccent" width="333"/>
<char name="dotlessi" width="278"/>
<char name="e" width="444"/>
<char name="eacute" width="444"/>
<char name="ecircumflex" width="444"/>
<char name="edieresis" width="444"/>
<char name="egrave" width="444"/>
<char name="eight" width="500"/>
<char name="ellipsis" width="889"/>
<char name="emdash" width="889"/>
<char name="endash" width="500"/>
<char name="equal" width="675"/>
<char name="eth" width="500"/>
<char name="exclam" width="333"/>
<char name="exclamdown" width="389"/>
<char name="f" width="278"/>
<char name="fi" width="500"/>
<char name="five" width="500"/>
<char name="fl" width="500"/>
<char name="florin" width="500"/>
<char name="four" width="500"/>
<char name="fraction" width="167"/>
<char name="g" width="500"/>
<char name="germandbls" width="500"/>
<char name="grave" width="333"/>
<char name="greater" width="675"/>
<char name="guillemotleft" width="500"/>
<char name="guillemotright" width="500"/>
<char name="guilsinglleft" width="333"/>
<char name="guilsinglright" width="333"/>
<char name="h" width="500"/>
<char name="hungarumlaut" width="333"/>
<char name="hyphen" width="333"/>
<char name="i" width="278"/>
<char name="iacute" width="278"/>
<char name="icircumflex" width="278"/>
<char name="idieresis" width="278"/>
<char name="igrave" width="278"/>
<char name="j" width="278"/>
<char name="k" width="444"/>
<char name="l" width="278"/>
<char name="less" width="675"/>
<char name="logicalnot" width="675"/>
<char name="lslash" width="278"/>
<char name="m" width="722"/>
<char name="macron" width="333"/>
<char name="minus" width="675"/>
<char name="mu" width="500"/>
<char name="multiply" width="675"/>
<char name="n" width="500"/>
<char name="nine" width="500"/>
<char name="ntilde" width="500"/>
<char name="numbersign" width="500"/>
<char name="o" width="500"/>
<char name="oacute" width="500"/>
<char name="ocircumflex" width="500"/>
<char name="odieresis" width="500"/>
<char name="oe" width="667"/>
<char name="ogonek" width="333"/>
<char name="ograve" width="500"/>
<char name="one" width="500"/>
<char name="onehalf" width="750"/>
<char name="onequarter" width="750"/>
<char name="onesuperior" width="300"/>
<char name="ordfeminine" width="276"/>
<char name="ordmasculine" width="310"/>
<char name="oslash" width="500"/>
<char name="otilde" width="500"/>
<char name="p" width="500"/>
<char name="paragraph" width="523"/>
<char name="parenleft" width="333"/>
<char name="parenright" width="333"/>
<char name="percent" width="833"/>
<char name="period" width="250"/>
<char name="periodcentered" width="250"/>
<char name="perthousand" width="1000"/>
<char name="plus" width="675"/>
<char name="plusminus" width="675"/>
<char name="q" width="500"/>
<char name="question" width="500"/>
<char name="questiondown" width="500"/>
<char name="quotedbl" width="420"/>
<char name="quotedblbase" width="556"/>
<char name="quotedblleft" width="556"/>
<char name="quotedblright" width="556"/>
<char name="quoteleft" width="333"/>
<char name="quoteright" width="333"/>
<char name="quotesinglbase" width="333"/>
<char name="quotesingle" width="214"/>
<char name="r" width="389"/>
<char name="registered" width="760"/>
<char name="ring" width="333"/>
<char name="s" width="389"/>
<char name="scaron" width="389"/>
<char name="section" width="500"/>
<char name="semicolon" width="333"/>
<char name="seven" width="500"/>
<char name="six" width="500"/>
<char name="slash" width="278"/>
<char name="space" width="250"/>
<char-metrics>
<char name="A" width="611" llx="-51" lly="0" urx="564" ury="668"/>
<char name="AE" width="889" llx="-27" lly="0" urx="911" ury="653"/>
<char name="Aacute" width="611" llx="-51" lly="0" urx="564" ury="876"/>
<char name="Acircumflex" width="611" llx="-51" lly="0" urx="564" ury="873"/>
<char name="Adieresis" width="611" llx="-51" lly="0" urx="564" ury="818"/>
<char name="Agrave" width="611" llx="-51" lly="0" urx="564" ury="876"/>
<char name="Aring" width="611" llx="-51" lly="0" urx="564" ury="883"/>
<char name="Atilde" width="611" llx="-51" lly="0" urx="566" ury="836"/>
<char name="B" width="611" llx="-8" lly="0" urx="588" ury="653"/>
<char name="C" width="667" llx="66" lly="-18" urx="689" ury="666"/>
<char name="Ccedilla" width="667" llx="66" lly="-217" urx="689" ury="666"/>
<char name="D" width="722" llx="-8" lly="0" urx="700" ury="653"/>
<char name="E" width="611" llx="-1" lly="0" urx="634" ury="653"/>
<char name="Eacute" width="611" llx="-1" lly="0" urx="634" ury="876"/>
<char name="Ecircumflex" width="611" llx="-1" lly="0" urx="634" ury="873"/>
<char name="Edieresis" width="611" llx="-1" lly="0" urx="634" ury="818"/>
<char name="Egrave" width="611" llx="-1" lly="0" urx="634" ury="876"/>
<char name="Eth" width="722" llx="-8" lly="0" urx="700" ury="653"/>
<char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="611" llx="8" lly="0" urx="645" ury="653"/>
<char name="G" width="722" llx="52" lly="-18" urx="722" ury="666"/>
<char name="H" width="722" llx="-8" lly="0" urx="767" ury="653"/>
<char name="I" width="333" llx="-8" lly="0" urx="384" ury="653"/>
<char name="Iacute" width="333" llx="-8" lly="0" urx="433" ury="876"/>
<char name="Icircumflex" width="333" llx="-8" lly="0" urx="425" ury="873"/>
<char name="Idieresis" width="333" llx="-8" lly="0" urx="435" ury="818"/>
<char name="Igrave" width="333" llx="-8" lly="0" urx="384" ury="876"/>
<char name="J" width="444" llx="-6" lly="-18" urx="491" ury="653"/>
<char name="K" width="667" llx="7" lly="0" urx="722" ury="653"/>
<char name="L" width="556" llx="-8" lly="0" urx="559" ury="653"/>
<char name="Lslash" width="556" llx="-8" lly="0" urx="559" ury="653"/>
<char name="M" width="833" llx="-18" lly="0" urx="873" ury="653"/>
<char name="N" width="667" llx="-20" lly="-15" urx="727" ury="653"/>
<char name="Ntilde" width="667" llx="-20" lly="-15" urx="727" ury="836"/>
<char name="O" width="722" llx="60" lly="-18" urx="699" ury="666"/>
<char name="OE" width="944" llx="49" lly="-8" urx="964" ury="666"/>
<char name="Oacute" width="722" llx="60" lly="-18" urx="699" ury="876"/>
<char name="Ocircumflex" width="722" llx="60" lly="-18" urx="699" ury="873"/>
<char name="Odieresis" width="722" llx="60" lly="-18" urx="699" ury="818"/>
<char name="Ograve" width="722" llx="60" lly="-18" urx="699" ury="876"/>
<char name="Oslash" width="722" llx="60" lly="-105" urx="699" ury="722"/>
<char name="Otilde" width="722" llx="60" lly="-18" urx="699" ury="836"/>
<char name="P" width="611" llx="0" lly="0" urx="605" ury="653"/>
<char name="Q" width="722" llx="59" lly="-182" urx="699" ury="666"/>
<char name="R" width="611" llx="-13" lly="0" urx="588" ury="653"/>
<char name="S" width="500" llx="17" lly="-18" urx="508" ury="667"/>
<char name="Scaron" width="500" llx="17" lly="-18" urx="520" ury="873"/>
<char name="T" width="556" llx="59" lly="0" urx="633" ury="653"/>
<char name="Thorn" width="611" llx="0" lly="0" urx="569" ury="653"/>
<char name="U" width="722" llx="102" lly="-18" urx="765" ury="653"/>
<char name="Uacute" width="722" llx="102" lly="-18" urx="765" ury="876"/>
<char name="Ucircumflex" width="722" llx="102" lly="-18" urx="765" ury="873"/>
<char name="Udieresis" width="722" llx="102" lly="-18" urx="765" ury="818"/>
<char name="Ugrave" width="722" llx="102" lly="-18" urx="765" ury="876"/>
<char name="V" width="611" llx="76" lly="-18" urx="688" ury="653"/>
<char name="W" width="833" llx="71" lly="-18" urx="906" ury="653"/>
<char name="X" width="611" llx="-29" lly="0" urx="655" ury="653"/>
<char name="Y" width="556" llx="78" lly="0" urx="633" ury="653"/>
<char name="Yacute" width="556" llx="78" lly="0" urx="633" ury="876"/>
<char name="Ydieresis" width="556" llx="78" lly="0" urx="633" ury="818"/>
<char name="Z" width="556" llx="-6" lly="0" urx="606" ury="653"/>
<char name="Zcaron" width="556" llx="-6" lly="0" urx="606" ury="873"/>
<char name="a" width="500" llx="17" lly="-11" urx="476" ury="441"/>
<char name="aacute" width="500" llx="17" lly="-11" urx="487" ury="664"/>
<char name="acircumflex" width="500" llx="17" lly="-11" urx="476" ury="661"/>
<char name="acute" width="333" llx="180" lly="494" urx="403" ury="664"/>
<char name="adieresis" width="500" llx="17" lly="-11" urx="489" ury="606"/>
<char name="ae" width="667" llx="23" lly="-11" urx="640" ury="441"/>
<char name="agrave" width="500" llx="17" lly="-11" urx="476" ury="664"/>
<char name="ampersand" width="778" llx="76" lly="-18" urx="723" ury="666"/>
<char name="aring" width="500" llx="17" lly="-11" urx="476" ury="691"/>
<char name="asciicircum" width="422" llx="0" lly="301" urx="422" ury="666"/>
<char name="asciitilde" width="541" llx="40" lly="183" urx="502" ury="323"/>
<char name="asterisk" width="500" llx="128" lly="255" urx="492" ury="666"/>
<char name="at" width="920" llx="118" lly="-18" urx="806" ury="666"/>
<char name="atilde" width="500" llx="17" lly="-11" urx="511" ury="624"/>
<char name="b" width="500" llx="23" lly="-11" urx="473" ury="683"/>
<char name="backslash" width="278" llx="-41" lly="-18" urx="319" ury="666"/>
<char name="bar" width="275" llx="105" lly="-217" urx="171" ury="783"/>
<char name="braceleft" width="400" llx="51" lly="-177" urx="407" ury="687"/>
<char name="braceright" width="400" llx="-7" lly="-177" urx="349" ury="687"/>
<char name="bracketleft" width="389" llx="21" lly="-153" urx="391" ury="663"/>
<char name="bracketright" width="389" llx="12" lly="-153" urx="382" ury="663"/>
<char name="breve" width="333" llx="117" lly="492" urx="418" ury="650"/>
<char name="brokenbar" width="275" llx="105" lly="-142" urx="171" ury="708"/>
<char name="bullet" width="350" llx="40" lly="191" urx="310" ury="461"/>
<char name="c" width="444" llx="30" lly="-11" urx="425" ury="441"/>
<char name="caron" width="333" llx="121" lly="492" urx="426" ury="661"/>
<char name="ccedilla" width="444" llx="30" lly="-217" urx="425" ury="441"/>
<char name="cedilla" width="333" llx="-30" lly="-217" urx="182" ury="0"/>
<char name="cent" width="500" llx="77" lly="-143" urx="472" ury="560"/>
<char name="circumflex" width="333" llx="91" lly="492" urx="385" ury="661"/>
<char name="colon" width="333" llx="50" lly="-11" urx="261" ury="441"/>
<char name="comma" width="250" llx="-4" lly="-129" urx="135" ury="101"/>
<char name="copyright" width="760" llx="41" lly="-18" urx="719" ury="666"/>
<char name="currency" width="500" llx="-22" lly="53" urx="522" ury="597"/>
<char name="d" width="500" llx="15" lly="-13" urx="527" ury="683"/>
<char name="dagger" width="500" llx="101" lly="-159" urx="488" ury="666"/>
<char name="daggerdbl" width="500" llx="22" lly="-143" urx="491" ury="666"/>
<char name="degree" width="400" llx="101" lly="390" urx="387" ury="676"/>
<char name="dieresis" width="333" llx="107" lly="548" urx="405" ury="646"/>
<char name="divide" width="675" llx="86" lly="-11" urx="590" ury="517"/>
<char name="dollar" width="500" llx="31" lly="-89" urx="497" ury="731"/>
<char name="dotaccent" width="333" llx="207" lly="548" urx="305" ury="646"/>
<char name="dotlessi" width="278" llx="49" lly="-11" urx="235" ury="441"/>
<char name="e" width="444" llx="31" lly="-11" urx="412" ury="441"/>
<char name="eacute" width="444" llx="31" lly="-11" urx="459" ury="664"/>
<char name="ecircumflex" width="444" llx="31" lly="-11" urx="441" ury="661"/>
<char name="edieresis" width="444" llx="31" lly="-11" urx="451" ury="606"/>
<char name="egrave" width="444" llx="31" lly="-11" urx="412" ury="664"/>
<char name="eight" width="500" llx="30" lly="-7" urx="493" ury="676"/>
<char name="ellipsis" width="889" llx="57" lly="-11" urx="762" ury="100"/>
<char name="emdash" width="889" llx="-6" lly="197" urx="894" ury="243"/>
<char name="endash" width="500" llx="-6" lly="197" urx="505" ury="243"/>
<char name="equal" width="675" llx="86" lly="120" urx="590" ury="386"/>
<char name="eth" width="500" llx="27" lly="-11" urx="482" ury="683"/>
<char name="exclam" width="333" llx="39" lly="-11" urx="302" ury="667"/>
<char name="exclamdown" width="389" llx="59" lly="-205" urx="322" ury="473"/>
<char name="f" width="278" llx="-147" lly="-207" urx="424" ury="678"/>
<char name="fi" width="500" llx="-141" lly="-207" urx="481" ury="681"/>
<char name="five" width="500" llx="15" lly="-7" urx="491" ury="666"/>
<char name="fl" width="500" llx="-141" lly="-204" urx="518" ury="682"/>
<char name="florin" width="500" llx="25" lly="-182" urx="507" ury="682"/>
<char name="four" width="500" llx="1" lly="0" urx="479" ury="676"/>
<char name="fraction" width="167" llx="-169" lly="-10" urx="337" ury="676"/>
<char name="g" width="500" llx="8" lly="-206" urx="472" ury="441"/>
<char name="germandbls" width="500" llx="-168" lly="-207" urx="493" ury="679"/>
<char name="grave" width="333" llx="121" lly="492" urx="311" ury="664"/>
<char name="greater" width="675" llx="84" lly="-8" urx="592" ury="514"/>
<char name="guillemotleft" width="500" llx="53" lly="37" urx="445" ury="403"/>
<char name="guillemotright" width="500" llx="55" lly="37" urx="447" ury="403"/>
<char name="guilsinglleft" width="333" llx="51" lly="37" urx="281" ury="403"/>
<char name="guilsinglright" width="333" llx="52" lly="37" urx="282" ury="403"/>
<char name="h" width="500" llx="19" lly="-9" urx="478" ury="683"/>
<char name="hungarumlaut" width="333" llx="93" lly="494" urx="486" ury="664"/>
<char name="hyphen" width="333" llx="49" lly="192" urx="282" ury="255"/>
<char name="i" width="278" llx="49" lly="-11" urx="264" ury="654"/>
<char name="iacute" width="278" llx="49" lly="-11" urx="355" ury="664"/>
<char name="icircumflex" width="278" llx="33" lly="-11" urx="327" ury="661"/>
<char name="idieresis" width="278" llx="49" lly="-11" urx="352" ury="606"/>
<char name="igrave" width="278" llx="49" lly="-11" urx="284" ury="664"/>
<char name="j" width="278" llx="-124" lly="-207" urx="276" ury="654"/>
<char name="k" width="444" llx="14" lly="-11" urx="461" ury="683"/>
<char name="l" width="278" llx="41" lly="-11" urx="279" ury="683"/>
<char name="less" width="675" llx="84" lly="-8" urx="592" ury="514"/>
<char name="logicalnot" width="675" llx="86" lly="108" urx="590" ury="386"/>
<char name="lslash" width="278" llx="41" lly="-11" urx="312" ury="683"/>
<char name="m" width="722" llx="12" lly="-9" urx="704" ury="441"/>
<char name="macron" width="333" llx="99" lly="532" urx="411" ury="583"/>
<char name="minus" width="675" llx="86" lly="220" urx="590" ury="286"/>
<char name="mu" width="500" llx="-30" lly="-209" urx="497" ury="428"/>
<char name="multiply" width="675" llx="93" lly="8" urx="582" ury="497"/>
<char name="n" width="500" llx="14" lly="-9" urx="474" ury="441"/>
<char name="nine" width="500" llx="23" lly="-17" urx="492" ury="676"/>
<char name="ntilde" width="500" llx="14" lly="-9" urx="476" ury="624"/>
<char name="numbersign" width="500" llx="2" lly="0" urx="540" ury="676"/>
<char name="o" width="500" llx="27" lly="-11" urx="468" ury="441"/>
<char name="oacute" width="500" llx="27" lly="-11" urx="487" ury="664"/>
<char name="ocircumflex" width="500" llx="27" lly="-11" urx="468" ury="661"/>
<char name="odieresis" width="500" llx="27" lly="-11" urx="489" ury="606"/>
<char name="oe" width="667" llx="20" lly="-12" urx="646" ury="441"/>
<char name="ogonek" width="333" llx="20" lly="-169" urx="203" ury="40"/>
<char name="ograve" width="500" llx="27" lly="-11" urx="468" ury="664"/>
<char name="one" width="500" llx="49" lly="0" urx="409" ury="676"/>
<char name="onehalf" width="750" llx="34" lly="-10" urx="749" ury="676"/>
<char name="onequarter" width="750" llx="33" lly="-10" urx="736" ury="676"/>
<char name="onesuperior" width="300" llx="43" lly="271" urx="284" ury="676"/>
<char name="ordfeminine" width="276" llx="42" lly="406" urx="352" ury="676"/>
<char name="ordmasculine" width="310" llx="67" lly="406" urx="362" ury="676"/>
<char name="oslash" width="500" llx="28" lly="-135" urx="469" ury="554"/>
<char name="otilde" width="500" llx="27" lly="-11" urx="496" ury="624"/>
<char name="p" width="500" llx="-75" lly="-205" urx="469" ury="441"/>
<char name="paragraph" width="523" llx="55" lly="-123" urx="616" ury="653"/>
<char name="parenleft" width="333" llx="42" lly="-181" urx="315" ury="669"/>
<char name="parenright" width="333" llx="16" lly="-180" urx="289" ury="669"/>
<char name="percent" width="833" llx="79" lly="-13" urx="790" ury="676"/>
<char name="period" width="250" llx="27" lly="-11" urx="138" ury="100"/>
<char name="periodcentered" width="250" llx="70" lly="199" urx="181" ury="310"/>
<char name="perthousand" width="1000" llx="25" lly="-19" urx="1010" ury="706"/>
<char name="plus" width="675" llx="86" lly="0" urx="590" ury="506"/>
<char name="plusminus" width="675" llx="86" lly="0" urx="590" ury="506"/>
<char name="q" width="500" llx="25" lly="-209" urx="483" ury="441"/>
<char name="question" width="500" llx="132" lly="-12" urx="472" ury="664"/>
<char name="questiondown" width="500" llx="28" lly="-205" urx="368" ury="471"/>
<char name="quotedbl" width="420" llx="144" lly="421" urx="432" ury="666"/>
<char name="quotedblbase" width="556" llx="57" lly="-129" urx="405" ury="101"/>
<char name="quotedblleft" width="556" llx="166" lly="436" urx="514" ury="666"/>
<char name="quotedblright" width="556" llx="151" lly="436" urx="499" ury="666"/>
<char name="quoteleft" width="333" llx="171" lly="436" urx="310" ury="666"/>
<char name="quoteright" width="333" llx="151" lly="436" urx="290" ury="666"/>
<char name="quotesinglbase" width="333" llx="44" lly="-129" urx="183" ury="101"/>
<char name="quotesingle" width="214" llx="132" lly="421" urx="241" ury="666"/>
<char name="r" width="389" llx="45" lly="0" urx="412" ury="441"/>
<char name="registered" width="760" llx="41" lly="-18" urx="719" ury="666"/>
<char name="ring" width="333" llx="155" lly="492" urx="355" ury="691"/>
<char name="s" width="389" llx="16" lly="-13" urx="366" ury="442"/>
<char name="scaron" width="389" llx="16" lly="-13" urx="454" ury="661"/>
<char name="section" width="500" llx="53" lly="-162" urx="461" ury="666"/>
<char name="semicolon" width="333" llx="27" lly="-129" urx="261" ury="441"/>
<char name="seven" width="500" llx="75" lly="-8" urx="537" ury="666"/>
<char name="six" width="500" llx="30" lly="-7" urx="521" ury="686"/>
<char name="slash" width="278" llx="-65" lly="-18" urx="386" ury="666"/>
<char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="250"/>
<char name="sterling" width="500"/>
<char name="t" width="278"/>
<char name="thorn" width="500"/>
<char name="three" width="500"/>
<char name="threequarters" width="750"/>
<char name="threesuperior" width="300"/>
<char name="tilde" width="333"/>
<char name="trademark" width="980"/>
<char name="two" width="500"/>
<char name="twosuperior" width="300"/>
<char name="u" width="500"/>
<char name="uacute" width="500"/>
<char name="ucircumflex" width="500"/>
<char name="udieresis" width="500"/>
<char name="ugrave" width="500"/>
<char name="underscore" width="500"/>
<char name="v" width="444"/>
<char name="w" width="667"/>
<char name="x" width="444"/>
<char name="y" width="444"/>
<char name="yacute" width="444"/>
<char name="ydieresis" width="444"/>
<char name="yen" width="500"/>
<char name="z" width="389"/>
<char name="zcaron" width="389"/>
<char name="zero" width="500"/>
</widths>
<char name="sterling" width="500" llx="10" lly="-6" urx="517" ury="670"/>
<char name="t" width="278" llx="37" lly="-11" urx="296" ury="546"/>
<char name="thorn" width="500" llx="-75" lly="-205" urx="469" ury="683"/>
<char name="three" width="500" llx="15" lly="-7" urx="465" ury="676"/>
<char name="threequarters" width="750" llx="23" lly="-10" urx="736" ury="676"/>
<char name="threesuperior" width="300" llx="43" lly="268" urx="339" ury="676"/>
<char name="tilde" width="333" llx="100" lly="517" urx="427" ury="624"/>
<char name="trademark" width="980" llx="30" lly="247" urx="957" ury="653"/>
<char name="two" width="500" llx="12" lly="0" urx="452" ury="676"/>
<char name="twosuperior" width="300" llx="33" lly="271" urx="324" ury="676"/>
<char name="u" width="500" llx="42" lly="-11" urx="475" ury="441"/>
<char name="uacute" width="500" llx="42" lly="-11" urx="477" ury="664"/>
<char name="ucircumflex" width="500" llx="42" lly="-11" urx="475" ury="661"/>
<char name="udieresis" width="500" llx="42" lly="-11" urx="479" ury="606"/>
<char name="ugrave" width="500" llx="42" lly="-11" urx="475" ury="664"/>
<char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/>
<char name="v" width="444" llx="21" lly="-18" urx="426" ury="441"/>
<char name="w" width="667" llx="16" lly="-18" urx="648" ury="441"/>
<char name="x" width="444" llx="-27" lly="-11" urx="447" ury="441"/>
<char name="y" width="444" llx="-24" lly="-206" urx="426" ury="441"/>
<char name="yacute" width="444" llx="-24" lly="-206" urx="459" ury="664"/>
<char name="ydieresis" width="444" llx="-24" lly="-206" urx="441" ury="606"/>
<char name="yen" width="500" llx="27" lly="0" urx="603" ury="653"/>
<char name="z" width="389" llx="-2" lly="-81" urx="380" ury="428"/>
<char name="zcaron" width="389" llx="-2" lly="-81" urx="434" ury="661"/>
<char name="zero" width="500" llx="32" lly="-7" urx="497" ury="676"/>
</char-metrics>
<kerning kpx1="79">
<pair kern="-55" kpx2="65"/>
<pair kern="-50" kpx2="87"/>
@@ -641,4 +642,4 @@
<pair kern="0" kpx2="121"/>
<pair kern="-40" kpx2="118"/>
</kerning>
</font-metrics>
</font-metrics>

+ 233
- 232
src/codegen/fonts/TimesRoman.xml View File

@@ -22,245 +22,246 @@
<family-name>Times</family-name>
<class-name>TimesRoman</class-name>
<encoding>StandardEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>662</cap-height>
<x-height>450</x-height>
<ascender>683</ascender>
<descender>-217</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="A" width="722"/>
<char name="AE" width="889"/>
<char name="Aacute" width="722"/>
<char name="Acircumflex" width="722"/>
<char name="Adieresis" width="722"/>
<char name="Agrave" width="722"/>
<char name="Aring" width="722"/>
<char name="Atilde" width="722"/>
<char name="B" width="667"/>
<char name="C" width="667"/>
<char name="Ccedilla" width="667"/>
<char name="D" width="722"/>
<char name="E" width="611"/>
<char name="Eacute" width="611"/>
<char name="Ecircumflex" width="611"/>
<char name="Edieresis" width="611"/>
<char name="Egrave" width="611"/>
<char name="Eth" width="722"/>
<char name="Euro" width="500"/>
<char name="F" width="556"/>
<char name="G" width="722"/>
<char name="H" width="722"/>
<char name="I" width="333"/>
<char name="Iacute" width="333"/>
<char name="Icircumflex" width="333"/>
<char name="Idieresis" width="333"/>
<char name="Igrave" width="333"/>
<char name="J" width="389"/>
<char name="K" width="722"/>
<char name="L" width="611"/>
<char name="Lslash" width="611"/>
<char name="M" width="889"/>
<char name="N" width="722"/>
<char name="Ntilde" width="722"/>
<char name="O" width="722"/>
<char name="OE" width="889"/>
<char name="Oacute" width="722"/>
<char name="Ocircumflex" width="722"/>
<char name="Odieresis" width="722"/>
<char name="Ograve" width="722"/>
<char name="Oslash" width="722"/>
<char name="Otilde" width="722"/>
<char name="P" width="556"/>
<char name="Q" width="722"/>
<char name="R" width="667"/>
<char name="S" width="556"/>
<char name="Scaron" width="556"/>
<char name="T" width="611"/>
<char name="Thorn" width="556"/>
<char name="U" width="722"/>
<char name="Uacute" width="722"/>
<char name="Ucircumflex" width="722"/>
<char name="Udieresis" width="722"/>
<char name="Ugrave" width="722"/>
<char name="V" width="722"/>
<char name="W" width="944"/>
<char name="X" width="722"/>
<char name="Y" width="722"/>
<char name="Yacute" width="722"/>
<char name="Ydieresis" width="722"/>
<char name="Z" width="611"/>
<char name="Zcaron" width="611"/>
<char name="a" width="444"/>
<char name="aacute" width="444"/>
<char name="acircumflex" width="444"/>
<char name="acute" width="333"/>
<char name="adieresis" width="444"/>
<char name="ae" width="667"/>
<char name="agrave" width="444"/>
<char name="ampersand" width="778"/>
<char name="aring" width="444"/>
<char name="asciicircum" width="469"/>
<char name="asciitilde" width="541"/>
<char name="asterisk" width="500"/>
<char name="at" width="921"/>
<char name="atilde" width="444"/>
<char name="b" width="500"/>
<char name="backslash" width="278"/>
<char name="bar" width="200"/>
<char name="braceleft" width="480"/>
<char name="braceright" width="480"/>
<char name="bracketleft" width="333"/>
<char name="bracketright" width="333"/>
<char name="breve" width="333"/>
<char name="brokenbar" width="200"/>
<char name="bullet" width="350"/>
<char name="c" width="444"/>
<char name="caron" width="333"/>
<char name="ccedilla" width="444"/>
<char name="cedilla" width="333"/>
<char name="cent" width="500"/>
<char name="circumflex" width="333"/>
<char name="colon" width="278"/>
<char name="comma" width="250"/>
<char name="copyright" width="760"/>
<char name="currency" width="500"/>
<char name="d" width="500"/>
<char name="dagger" width="500"/>
<char name="daggerdbl" width="500"/>
<char name="degree" width="400"/>
<char name="dieresis" width="333"/>
<char name="divide" width="564"/>
<char name="dollar" width="500"/>
<char name="dotaccent" width="333"/>
<char name="dotlessi" width="278"/>
<char name="e" width="444"/>
<char name="eacute" width="444"/>
<char name="ecircumflex" width="444"/>
<char name="edieresis" width="444"/>
<char name="egrave" width="444"/>
<char name="eight" width="500"/>
<char name="ellipsis" width="1000"/>
<char name="emdash" width="1000"/>
<char name="endash" width="500"/>
<char name="equal" width="564"/>
<char name="eth" width="500"/>
<char name="exclam" width="333"/>
<char name="exclamdown" width="333"/>
<char name="f" width="333"/>
<char name="fi" width="556"/>
<char name="five" width="500"/>
<char name="fl" width="556"/>
<char name="florin" width="500"/>
<char name="four" width="500"/>
<char name="fraction" width="167"/>
<char name="g" width="500"/>
<char name="germandbls" width="500"/>
<char name="grave" width="333"/>
<char name="greater" width="564"/>
<char name="guillemotleft" width="500"/>
<char name="guillemotright" width="500"/>
<char name="guilsinglleft" width="333"/>
<char name="guilsinglright" width="333"/>
<char name="h" width="500"/>
<char name="hungarumlaut" width="333"/>
<char name="hyphen" width="333"/>
<char name="i" width="278"/>
<char name="iacute" width="278"/>
<char name="icircumflex" width="278"/>
<char name="idieresis" width="278"/>
<char name="igrave" width="278"/>
<char name="j" width="278"/>
<char name="k" width="500"/>
<char name="l" width="278"/>
<char name="less" width="564"/>
<char name="logicalnot" width="564"/>
<char name="lslash" width="278"/>
<char name="m" width="778"/>
<char name="macron" width="333"/>
<char name="minus" width="324"/>
<char name="mu" width="500"/>
<char name="multiply" width="564"/>
<char name="n" width="500"/>
<char name="nine" width="500"/>
<char name="ntilde" width="500"/>
<char name="numbersign" width="500"/>
<char name="o" width="500"/>
<char name="oacute" width="500"/>
<char name="ocircumflex" width="500"/>
<char name="odieresis" width="500"/>
<char name="oe" width="722"/>
<char name="ogonek" width="333"/>
<char name="ograve" width="500"/>
<char name="one" width="500"/>
<char name="onehalf" width="750"/>
<char name="onequarter" width="750"/>
<char name="onesuperior" width="300"/>
<char name="ordfeminine" width="276"/>
<char name="ordmasculine" width="310"/>
<char name="oslash" width="500"/>
<char name="otilde" width="500"/>
<char name="p" width="500"/>
<char name="paragraph" width="453"/>
<char name="parenleft" width="333"/>
<char name="parenright" width="333"/>
<char name="percent" width="833"/>
<char name="period" width="250"/>
<char name="periodcentered" width="250"/>
<char name="perthousand" width="1000"/>
<char name="plus" width="564"/>
<char name="plusminus" width="564"/>
<char name="q" width="500"/>
<char name="question" width="444"/>
<char name="questiondown" width="444"/>
<char name="quotedbl" width="408"/>
<char name="quotedblbase" width="444"/>
<char name="quotedblleft" width="444"/>
<char name="quotedblright" width="444"/>
<char name="quoteleft" width="333"/>
<char name="quoteright" width="333"/>
<char name="quotesinglbase" width="333"/>
<char name="quotesingle" width="180"/>
<char name="r" width="333"/>
<char name="registered" width="760"/>
<char name="ring" width="333"/>
<char name="s" width="389"/>
<char name="scaron" width="389"/>
<char name="section" width="500"/>
<char name="semicolon" width="278"/>
<char name="seven" width="500"/>
<char name="six" width="500"/>
<char name="slash" width="278"/>
<char name="space" width="250"/>
<char-metrics>
<char name="A" width="722" llx="15" lly="0" urx="706" ury="674"/>
<char name="AE" width="889" llx="0" lly="0" urx="863" ury="662"/>
<char name="Aacute" width="722" llx="15" lly="0" urx="706" ury="890"/>
<char name="Acircumflex" width="722" llx="15" lly="0" urx="706" ury="886"/>
<char name="Adieresis" width="722" llx="15" lly="0" urx="706" ury="835"/>
<char name="Agrave" width="722" llx="15" lly="0" urx="706" ury="890"/>
<char name="Aring" width="722" llx="15" lly="0" urx="706" ury="898"/>
<char name="Atilde" width="722" llx="15" lly="0" urx="706" ury="850"/>
<char name="B" width="667" llx="17" lly="0" urx="593" ury="662"/>
<char name="C" width="667" llx="28" lly="-14" urx="633" ury="676"/>
<char name="Ccedilla" width="667" llx="28" lly="-215" urx="633" ury="676"/>
<char name="D" width="722" llx="16" lly="0" urx="685" ury="662"/>
<char name="E" width="611" llx="12" lly="0" urx="597" ury="662"/>
<char name="Eacute" width="611" llx="12" lly="0" urx="597" ury="890"/>
<char name="Ecircumflex" width="611" llx="12" lly="0" urx="597" ury="886"/>
<char name="Edieresis" width="611" llx="12" lly="0" urx="597" ury="835"/>
<char name="Egrave" width="611" llx="12" lly="0" urx="597" ury="890"/>
<char name="Eth" width="722" llx="16" lly="0" urx="685" ury="662"/>
<char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/>
<char name="F" width="556" llx="12" lly="0" urx="546" ury="662"/>
<char name="G" width="722" llx="32" lly="-14" urx="709" ury="676"/>
<char name="H" width="722" llx="19" lly="0" urx="702" ury="662"/>
<char name="I" width="333" llx="18" lly="0" urx="315" ury="662"/>
<char name="Iacute" width="333" llx="18" lly="0" urx="317" ury="890"/>
<char name="Icircumflex" width="333" llx="11" lly="0" urx="322" ury="886"/>
<char name="Idieresis" width="333" llx="18" lly="0" urx="315" ury="835"/>
<char name="Igrave" width="333" llx="18" lly="0" urx="315" ury="890"/>
<char name="J" width="389" llx="10" lly="-14" urx="370" ury="662"/>
<char name="K" width="722" llx="34" lly="0" urx="723" ury="662"/>
<char name="L" width="611" llx="12" lly="0" urx="598" ury="662"/>
<char name="Lslash" width="611" llx="12" lly="0" urx="598" ury="662"/>
<char name="M" width="889" llx="12" lly="0" urx="863" ury="662"/>
<char name="N" width="722" llx="12" lly="-11" urx="707" ury="662"/>
<char name="Ntilde" width="722" llx="12" lly="-11" urx="707" ury="850"/>
<char name="O" width="722" llx="34" lly="-14" urx="688" ury="676"/>
<char name="OE" width="889" llx="30" lly="-6" urx="885" ury="668"/>
<char name="Oacute" width="722" llx="34" lly="-14" urx="688" ury="890"/>
<char name="Ocircumflex" width="722" llx="34" lly="-14" urx="688" ury="886"/>
<char name="Odieresis" width="722" llx="34" lly="-14" urx="688" ury="835"/>
<char name="Ograve" width="722" llx="34" lly="-14" urx="688" ury="890"/>
<char name="Oslash" width="722" llx="34" lly="-80" urx="688" ury="734"/>
<char name="Otilde" width="722" llx="34" lly="-14" urx="688" ury="850"/>
<char name="P" width="556" llx="16" lly="0" urx="542" ury="662"/>
<char name="Q" width="722" llx="34" lly="-178" urx="701" ury="676"/>
<char name="R" width="667" llx="17" lly="0" urx="659" ury="662"/>
<char name="S" width="556" llx="42" lly="-14" urx="491" ury="676"/>
<char name="Scaron" width="556" llx="42" lly="-14" urx="491" ury="886"/>
<char name="T" width="611" llx="17" lly="0" urx="593" ury="662"/>
<char name="Thorn" width="556" llx="16" lly="0" urx="542" ury="662"/>
<char name="U" width="722" llx="14" lly="-14" urx="705" ury="662"/>
<char name="Uacute" width="722" llx="14" lly="-14" urx="705" ury="890"/>
<char name="Ucircumflex" width="722" llx="14" lly="-14" urx="705" ury="886"/>
<char name="Udieresis" width="722" llx="14" lly="-14" urx="705" ury="835"/>
<char name="Ugrave" width="722" llx="14" lly="-14" urx="705" ury="890"/>
<char name="V" width="722" llx="16" lly="-11" urx="697" ury="662"/>
<char name="W" width="944" llx="5" lly="-11" urx="932" ury="662"/>
<char name="X" width="722" llx="10" lly="0" urx="704" ury="662"/>
<char name="Y" width="722" llx="22" lly="0" urx="703" ury="662"/>
<char name="Yacute" width="722" llx="22" lly="0" urx="703" ury="890"/>
<char name="Ydieresis" width="722" llx="22" lly="0" urx="703" ury="835"/>
<char name="Z" width="611" llx="9" lly="0" urx="597" ury="662"/>
<char name="Zcaron" width="611" llx="9" lly="0" urx="597" ury="886"/>
<char name="a" width="444" llx="37" lly="-10" urx="442" ury="460"/>
<char name="aacute" width="444" llx="37" lly="-10" urx="442" ury="678"/>
<char name="acircumflex" width="444" llx="37" lly="-10" urx="442" ury="674"/>
<char name="acute" width="333" llx="93" lly="507" urx="317" ury="678"/>
<char name="adieresis" width="444" llx="37" lly="-10" urx="442" ury="623"/>
<char name="ae" width="667" llx="38" lly="-10" urx="632" ury="460"/>
<char name="agrave" width="444" llx="37" lly="-10" urx="442" ury="678"/>
<char name="ampersand" width="778" llx="42" lly="-13" urx="750" ury="676"/>
<char name="aring" width="444" llx="37" lly="-10" urx="442" ury="711"/>
<char name="asciicircum" width="469" llx="24" lly="297" urx="446" ury="662"/>
<char name="asciitilde" width="541" llx="40" lly="183" urx="502" ury="323"/>
<char name="asterisk" width="500" llx="69" lly="265" urx="432" ury="676"/>
<char name="at" width="921" llx="116" lly="-14" urx="809" ury="676"/>
<char name="atilde" width="444" llx="37" lly="-10" urx="442" ury="638"/>
<char name="b" width="500" llx="3" lly="-10" urx="468" ury="683"/>
<char name="backslash" width="278" llx="-9" lly="-14" urx="287" ury="676"/>
<char name="bar" width="200" llx="67" lly="-218" urx="133" ury="782"/>
<char name="braceleft" width="480" llx="100" lly="-181" urx="350" ury="680"/>
<char name="braceright" width="480" llx="130" lly="-181" urx="380" ury="680"/>
<char name="bracketleft" width="333" llx="88" lly="-156" urx="299" ury="662"/>
<char name="bracketright" width="333" llx="34" lly="-156" urx="245" ury="662"/>
<char name="breve" width="333" llx="26" lly="507" urx="307" ury="664"/>
<char name="brokenbar" width="200" llx="67" lly="-143" urx="133" ury="707"/>
<char name="bullet" width="350" llx="40" lly="196" urx="310" ury="466"/>
<char name="c" width="444" llx="25" lly="-10" urx="412" ury="460"/>
<char name="caron" width="333" llx="11" lly="507" urx="322" ury="674"/>
<char name="ccedilla" width="444" llx="25" lly="-215" urx="412" ury="460"/>
<char name="cedilla" width="333" llx="52" lly="-215" urx="261" ury="0"/>
<char name="cent" width="500" llx="53" lly="-138" urx="448" ury="579"/>
<char name="circumflex" width="333" llx="11" lly="507" urx="322" ury="674"/>
<char name="colon" width="278" llx="81" lly="-11" urx="192" ury="459"/>
<char name="comma" width="250" llx="56" lly="-141" urx="195" ury="102"/>
<char name="copyright" width="760" llx="38" lly="-14" urx="722" ury="676"/>
<char name="currency" width="500" llx="-22" lly="58" urx="522" ury="602"/>
<char name="d" width="500" llx="27" lly="-10" urx="491" ury="683"/>
<char name="dagger" width="500" llx="59" lly="-149" urx="442" ury="676"/>
<char name="daggerdbl" width="500" llx="58" lly="-153" urx="442" ury="676"/>
<char name="degree" width="400" llx="57" lly="390" urx="343" ury="676"/>
<char name="dieresis" width="333" llx="18" lly="581" urx="315" ury="681"/>
<char name="divide" width="564" llx="30" lly="-10" urx="534" ury="516"/>
<char name="dollar" width="500" llx="44" lly="-87" urx="457" ury="727"/>
<char name="dotaccent" width="333" llx="118" lly="581" urx="216" ury="681"/>
<char name="dotlessi" width="278" llx="16" lly="0" urx="253" ury="460"/>
<char name="e" width="444" llx="25" lly="-10" urx="424" ury="460"/>
<char name="eacute" width="444" llx="25" lly="-10" urx="424" ury="678"/>
<char name="ecircumflex" width="444" llx="25" lly="-10" urx="424" ury="674"/>
<char name="edieresis" width="444" llx="25" lly="-10" urx="424" ury="623"/>
<char name="egrave" width="444" llx="25" lly="-10" urx="424" ury="678"/>
<char name="eight" width="500" llx="56" lly="-14" urx="445" ury="676"/>
<char name="ellipsis" width="1000" llx="111" lly="-11" urx="888" ury="100"/>
<char name="emdash" width="1000" llx="0" lly="201" urx="1000" ury="250"/>
<char name="endash" width="500" llx="0" lly="201" urx="500" ury="250"/>
<char name="equal" width="564" llx="30" lly="120" urx="534" ury="386"/>
<char name="eth" width="500" llx="29" lly="-10" urx="471" ury="686"/>
<char name="exclam" width="333" llx="130" lly="-9" urx="238" ury="676"/>
<char name="exclamdown" width="333" llx="97" lly="-218" urx="205" ury="467"/>
<char name="f" width="333" llx="20" lly="0" urx="383" ury="683"/>
<char name="fi" width="556" llx="31" lly="0" urx="521" ury="683"/>
<char name="five" width="500" llx="32" lly="-14" urx="438" ury="688"/>
<char name="fl" width="556" llx="32" lly="0" urx="521" ury="683"/>
<char name="florin" width="500" llx="7" lly="-189" urx="490" ury="676"/>
<char name="four" width="500" llx="12" lly="0" urx="472" ury="676"/>
<char name="fraction" width="167" llx="-168" lly="-14" urx="331" ury="676"/>
<char name="g" width="500" llx="28" lly="-218" urx="470" ury="460"/>
<char name="germandbls" width="500" llx="12" lly="-9" urx="468" ury="683"/>
<char name="grave" width="333" llx="19" lly="507" urx="242" ury="678"/>
<char name="greater" width="564" llx="28" lly="-8" urx="536" ury="514"/>
<char name="guillemotleft" width="500" llx="42" lly="33" urx="456" ury="416"/>
<char name="guillemotright" width="500" llx="44" lly="33" urx="458" ury="416"/>
<char name="guilsinglleft" width="333" llx="63" lly="33" urx="285" ury="416"/>
<char name="guilsinglright" width="333" llx="48" lly="33" urx="270" ury="416"/>
<char name="h" width="500" llx="9" lly="0" urx="487" ury="683"/>
<char name="hungarumlaut" width="333" llx="-3" lly="507" urx="377" ury="678"/>
<char name="hyphen" width="333" llx="39" lly="194" urx="285" ury="257"/>
<char name="i" width="278" llx="16" lly="0" urx="253" ury="683"/>
<char name="iacute" width="278" llx="16" lly="0" urx="290" ury="678"/>
<char name="icircumflex" width="278" llx="-16" lly="0" urx="295" ury="674"/>
<char name="idieresis" width="278" llx="-9" lly="0" urx="288" ury="623"/>
<char name="igrave" width="278" llx="-8" lly="0" urx="253" ury="678"/>
<char name="j" width="278" llx="-70" lly="-218" urx="194" ury="683"/>
<char name="k" width="500" llx="7" lly="0" urx="505" ury="683"/>
<char name="l" width="278" llx="19" lly="0" urx="257" ury="683"/>
<char name="less" width="564" llx="28" lly="-8" urx="536" ury="514"/>
<char name="logicalnot" width="564" llx="30" lly="108" urx="534" ury="386"/>
<char name="lslash" width="278" llx="19" lly="0" urx="259" ury="683"/>
<char name="m" width="778" llx="16" lly="0" urx="775" ury="460"/>
<char name="macron" width="333" llx="11" lly="547" urx="322" ury="601"/>
<char name="minus" width="324" llx="30" lly="220" urx="534" ury="286"/>
<char name="mu" width="500" llx="36" lly="-218" urx="512" ury="450"/>
<char name="multiply" width="564" llx="38" lly="8" urx="527" ury="497"/>
<char name="n" width="500" llx="16" lly="0" urx="485" ury="460"/>
<char name="nine" width="500" llx="30" lly="-22" urx="459" ury="676"/>
<char name="ntilde" width="500" llx="16" lly="0" urx="485" ury="638"/>
<char name="numbersign" width="500" llx="5" lly="0" urx="496" ury="662"/>
<char name="o" width="500" llx="29" lly="-10" urx="470" ury="460"/>
<char name="oacute" width="500" llx="29" lly="-10" urx="470" ury="678"/>
<char name="ocircumflex" width="500" llx="29" lly="-10" urx="470" ury="674"/>
<char name="odieresis" width="500" llx="29" lly="-10" urx="470" ury="623"/>
<char name="oe" width="722" llx="30" lly="-10" urx="690" ury="460"/>
<char name="ogonek" width="333" llx="62" lly="-165" urx="243" ury="0"/>
<char name="ograve" width="500" llx="29" lly="-10" urx="470" ury="678"/>
<char name="one" width="500" llx="111" lly="0" urx="394" ury="676"/>
<char name="onehalf" width="750" llx="31" lly="-14" urx="746" ury="676"/>
<char name="onequarter" width="750" llx="37" lly="-14" urx="718" ury="676"/>
<char name="onesuperior" width="300" llx="57" lly="270" urx="248" ury="676"/>
<char name="ordfeminine" width="276" llx="4" lly="394" urx="270" ury="676"/>
<char name="ordmasculine" width="310" llx="6" lly="394" urx="304" ury="676"/>
<char name="oslash" width="500" llx="29" lly="-112" urx="470" ury="551"/>
<char name="otilde" width="500" llx="29" lly="-10" urx="470" ury="638"/>
<char name="p" width="500" llx="5" lly="-217" urx="470" ury="460"/>
<char name="paragraph" width="453" llx="-22" lly="-154" urx="450" ury="662"/>
<char name="parenleft" width="333" llx="48" lly="-177" urx="304" ury="676"/>
<char name="parenright" width="333" llx="29" lly="-177" urx="285" ury="676"/>
<char name="percent" width="833" llx="61" lly="-13" urx="772" ury="676"/>
<char name="period" width="250" llx="70" lly="-11" urx="181" ury="100"/>
<char name="periodcentered" width="250" llx="70" lly="199" urx="181" ury="310"/>
<char name="perthousand" width="1000" llx="7" lly="-19" urx="994" ury="706"/>
<char name="plus" width="564" llx="30" lly="0" urx="534" ury="506"/>
<char name="plusminus" width="564" llx="30" lly="0" urx="534" ury="506"/>
<char name="q" width="500" llx="24" lly="-217" urx="488" ury="460"/>
<char name="question" width="444" llx="68" lly="-8" urx="414" ury="676"/>
<char name="questiondown" width="444" llx="30" lly="-218" urx="376" ury="466"/>
<char name="quotedbl" width="408" llx="77" lly="431" urx="331" ury="676"/>
<char name="quotedblbase" width="444" llx="45" lly="-141" urx="416" ury="102"/>
<char name="quotedblleft" width="444" llx="43" lly="433" urx="414" ury="676"/>
<char name="quotedblright" width="444" llx="30" lly="433" urx="401" ury="676"/>
<char name="quoteleft" width="333" llx="115" lly="433" urx="254" ury="676"/>
<char name="quoteright" width="333" llx="79" lly="433" urx="218" ury="676"/>
<char name="quotesinglbase" width="333" llx="79" lly="-141" urx="218" ury="102"/>
<char name="quotesingle" width="180" llx="48" lly="431" urx="133" ury="676"/>
<char name="r" width="333" llx="5" lly="0" urx="335" ury="460"/>
<char name="registered" width="760" llx="38" lly="-14" urx="722" ury="676"/>
<char name="ring" width="333" llx="67" lly="512" urx="266" ury="711"/>
<char name="s" width="389" llx="51" lly="-10" urx="348" ury="460"/>
<char name="scaron" width="389" llx="39" lly="-10" urx="350" ury="674"/>
<char name="section" width="500" llx="70" lly="-148" urx="426" ury="676"/>
<char name="semicolon" width="278" llx="80" lly="-141" urx="219" ury="459"/>
<char name="seven" width="500" llx="20" lly="-8" urx="449" ury="662"/>
<char name="six" width="500" llx="34" lly="-14" urx="468" ury="684"/>
<char name="slash" width="278" llx="-9" lly="-14" urx="287" ury="676"/>
<char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
<char name="nbsp" width="250"/>
<char name="sterling" width="500"/>
<char name="t" width="278"/>
<char name="thorn" width="500"/>
<char name="three" width="500"/>
<char name="threequarters" width="750"/>
<char name="threesuperior" width="300"/>
<char name="tilde" width="333"/>
<char name="trademark" width="980"/>
<char name="two" width="500"/>
<char name="twosuperior" width="300"/>
<char name="u" width="500"/>
<char name="uacute" width="500"/>
<char name="ucircumflex" width="500"/>
<char name="udieresis" width="500"/>
<char name="ugrave" width="500"/>
<char name="underscore" width="500"/>
<char name="v" width="500"/>
<char name="w" width="722"/>
<char name="x" width="500"/>
<char name="y" width="500"/>
<char name="yacute" width="500"/>
<char name="ydieresis" width="500"/>
<char name="yen" width="500"/>
<char name="z" width="444"/>
<char name="zcaron" width="444"/>
<char name="zero" width="500"/>
</widths>
<char name="sterling" width="500" llx="12" lly="-8" urx="490" ury="676"/>
<char name="t" width="278" llx="13" lly="-10" urx="279" ury="579"/>
<char name="thorn" width="500" llx="5" lly="-217" urx="470" ury="683"/>
<char name="three" width="500" llx="43" lly="-14" urx="431" ury="676"/>
<char name="threequarters" width="750" llx="15" lly="-14" urx="718" ury="676"/>
<char name="threesuperior" width="300" llx="15" lly="262" urx="291" ury="676"/>
<char name="tilde" width="333" llx="1" lly="532" urx="331" ury="638"/>
<char name="trademark" width="980" llx="30" lly="256" urx="957" ury="662"/>
<char name="two" width="500" llx="30" lly="0" urx="475" ury="676"/>
<char name="twosuperior" width="300" llx="1" lly="270" urx="296" ury="676"/>
<char name="u" width="500" llx="9" lly="-10" urx="479" ury="450"/>
<char name="uacute" width="500" llx="9" lly="-10" urx="479" ury="678"/>
<char name="ucircumflex" width="500" llx="9" lly="-10" urx="479" ury="674"/>
<char name="udieresis" width="500" llx="9" lly="-10" urx="479" ury="623"/>
<char name="ugrave" width="500" llx="9" lly="-10" urx="479" ury="678"/>
<char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/>
<char name="v" width="500" llx="19" lly="-14" urx="477" ury="450"/>
<char name="w" width="722" llx="21" lly="-14" urx="694" ury="450"/>
<char name="x" width="500" llx="17" lly="0" urx="479" ury="450"/>
<char name="y" width="500" llx="14" lly="-218" urx="475" ury="450"/>
<char name="yacute" width="500" llx="14" lly="-218" urx="475" ury="678"/>
<char name="ydieresis" width="500" llx="14" lly="-218" urx="475" ury="623"/>
<char name="yen" width="500" llx="-53" lly="0" urx="512" ury="662"/>
<char name="z" width="444" llx="27" lly="0" urx="418" ury="450"/>
<char name="zcaron" width="444" llx="27" lly="0" urx="418" ury="674"/>
<char name="zero" width="500" llx="24" lly="-14" urx="476" ury="676"/>
</char-metrics>
<kerning kpx1="79">
<pair kern="-35" kpx2="65"/>
<pair kern="-35" kpx2="87"/>

+ 207
- 205
src/codegen/fonts/ZapfDingbats.xml View File

@@ -21,214 +21,216 @@
<family-name>ZapfDingbats</family-name>
<class-name>ZapfDingbats</class-name>
<encoding>ZapfDingbatsEncoding</encoding>
<underline-position>-100</underline-position>
<underline-thickness>50</underline-thickness>
<cap-height>820</cap-height>
<x-height>426</x-height>
<ascender>820</ascender>
<descender>-143</descender>
<first-char>32</first-char>
<last-char>255</last-char>
<widths>
<char name="space" width="278"/>
<char name="a1" width="974"/>
<char name="a2" width="961"/>
<char name="a202" width="974"/>
<char name="a3" width="980"/>
<char name="a4" width="719"/>
<char name="a5" width="789"/>
<char name="a119" width="790"/>
<char name="a118" width="791"/>
<char name="a117" width="690"/>
<char name="a11" width="960"/>
<char name="a12" width="939"/>
<char name="a13" width="549"/>
<char name="a14" width="855"/>
<char name="a15" width="911"/>
<char name="a16" width="933"/>
<char name="a105" width="911"/>
<char name="a17" width="945"/>
<char name="a18" width="974"/>
<char name="a19" width="755"/>
<char name="a20" width="846"/>
<char name="a21" width="762"/>
<char name="a22" width="761"/>
<char name="a23" width="571"/>
<char name="a24" width="677"/>
<char name="a25" width="763"/>
<char name="a26" width="760"/>
<char name="a27" width="759"/>
<char name="a28" width="754"/>
<char name="a6" width="494"/>
<char name="a7" width="552"/>
<char name="a8" width="537"/>
<char name="a9" width="577"/>
<char name="a10" width="692"/>
<char name="a29" width="786"/>
<char name="a30" width="788"/>
<char name="a31" width="788"/>
<char name="a32" width="790"/>
<char name="a33" width="793"/>
<char name="a34" width="794"/>
<char name="a35" width="816"/>
<char name="a36" width="823"/>
<char name="a37" width="789"/>
<char name="a38" width="841"/>
<char name="a39" width="823"/>
<char name="a40" width="833"/>
<char name="a41" width="816"/>
<char name="a42" width="831"/>
<char name="a43" width="923"/>
<char name="a44" width="744"/>
<char name="a45" width="723"/>
<char name="a46" width="749"/>
<char name="a47" width="790"/>
<char name="a48" width="792"/>
<char name="a49" width="695"/>
<char name="a50" width="776"/>
<char name="a51" width="768"/>
<char name="a52" width="792"/>
<char name="a53" width="759"/>
<char name="a54" width="707"/>
<char name="a55" width="708"/>
<char name="a56" width="682"/>
<char name="a57" width="701"/>
<char name="a58" width="826"/>
<char name="a59" width="815"/>
<char name="a60" width="789"/>
<char name="a61" width="789"/>
<char name="a62" width="707"/>
<char name="a63" width="687"/>
<char name="a64" width="696"/>
<char name="a65" width="689"/>
<char name="a66" width="786"/>
<char name="a67" width="787"/>
<char name="a68" width="713"/>
<char name="a69" width="791"/>
<char name="a70" width="785"/>
<char name="a71" width="791"/>
<char name="a72" width="873"/>
<char name="a73" width="761"/>
<char name="a74" width="762"/>
<char name="a203" width="762"/>
<char name="a75" width="759"/>
<char name="a204" width="759"/>
<char name="a76" width="892"/>
<char name="a77" width="892"/>
<char name="a78" width="788"/>
<char name="a79" width="784"/>
<char name="a81" width="438"/>
<char name="a82" width="138"/>
<char name="a83" width="277"/>
<char name="a84" width="415"/>
<char name="a97" width="392"/>
<char name="a98" width="392"/>
<char name="a99" width="668"/>
<char name="a100" width="668"/>
<char name="a101" width="732"/>
<char name="a102" width="544"/>
<char name="a103" width="544"/>
<char name="a104" width="910"/>
<char name="a106" width="667"/>
<char name="a107" width="760"/>
<char name="a108" width="760"/>
<char name="a112" width="776"/>
<char name="a111" width="595"/>
<char name="a110" width="694"/>
<char name="a109" width="626"/>
<char name="a120" width="788"/>
<char name="a121" width="788"/>
<char name="a122" width="788"/>
<char name="a123" width="788"/>
<char name="a124" width="788"/>
<char name="a125" width="788"/>
<char name="a126" width="788"/>
<char name="a127" width="788"/>
<char name="a128" width="788"/>
<char name="a129" width="788"/>
<char name="a130" width="788"/>
<char name="a131" width="788"/>
<char name="a132" width="788"/>
<char name="a133" width="788"/>
<char name="a134" width="788"/>
<char name="a135" width="788"/>
<char name="a136" width="788"/>
<char name="a137" width="788"/>
<char name="a138" width="788"/>
<char name="a139" width="788"/>
<char name="a140" width="788"/>
<char name="a141" width="788"/>
<char name="a142" width="788"/>
<char name="a143" width="788"/>
<char name="a144" width="788"/>
<char name="a145" width="788"/>
<char name="a146" width="788"/>
<char name="a147" width="788"/>
<char name="a148" width="788"/>
<char name="a149" width="788"/>
<char name="a150" width="788"/>
<char name="a151" width="788"/>
<char name="a152" width="788"/>
<char name="a153" width="788"/>
<char name="a154" width="788"/>
<char name="a155" width="788"/>
<char name="a156" width="788"/>
<char name="a157" width="788"/>
<char name="a158" width="788"/>
<char name="a159" width="788"/>
<char name="a160" width="894"/>
<char name="a161" width="838"/>
<char name="a163" width="1016"/>
<char name="a164" width="458"/>
<char name="a196" width="748"/>
<char name="a165" width="924"/>
<char name="a192" width="748"/>
<char name="a166" width="918"/>
<char name="a167" width="927"/>
<char name="a168" width="928"/>
<char name="a169" width="928"/>
<char name="a170" width="834"/>
<char name="a171" width="873"/>
<char name="a172" width="828"/>
<char name="a173" width="924"/>
<char name="a162" width="924"/>
<char name="a174" width="917"/>
<char name="a175" width="930"/>
<char name="a176" width="931"/>
<char name="a177" width="463"/>
<char name="a178" width="883"/>
<char name="a179" width="836"/>
<char name="a193" width="836"/>
<char name="a180" width="867"/>
<char name="a199" width="867"/>
<char name="a181" width="696"/>
<char name="a200" width="696"/>
<char name="a182" width="874"/>
<char name="a201" width="874"/>
<char name="a183" width="760"/>
<char name="a184" width="946"/>
<char name="a197" width="771"/>
<char name="a185" width="865"/>
<char name="a194" width="771"/>
<char name="a198" width="888"/>
<char name="a186" width="967"/>
<char name="a195" width="888"/>
<char name="a187" width="831"/>
<char name="a188" width="873"/>
<char name="a189" width="927"/>
<char name="a190" width="970"/>
<char name="a191" width="918"/>
<char name="a86" width="410"/>
<char name="a85" width="509"/>
<char name="a95" width="334"/>
<char name="a205" width="509"/>
<char name="a89" width="390"/>
<char name="a87" width="234"/>
<char name="a91" width="276"/>
<char name="a90" width="390"/>
<char name="a206" width="410"/>
<char name="a94" width="317"/>
<char name="a93" width="317"/>
<char name="a92" width="276"/>
<char name="a96" width="334"/>
<char name="a88" width="234"/>
</widths>
</font-metrics>
<char-metrics>
<char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
<char name="a1" width="974" llx="35" lly="72" urx="939" ury="621"/>
<char name="a2" width="961" llx="35" lly="81" urx="927" ury="611"/>
<char name="a202" width="974" llx="35" lly="72" urx="939" ury="621"/>
<char name="a3" width="980" llx="35" lly="0" urx="945" ury="692"/>
<char name="a4" width="719" llx="34" lly="139" urx="685" ury="566"/>
<char name="a5" width="789" llx="35" lly="-14" urx="755" ury="705"/>
<char name="a119" width="790" llx="35" lly="-14" urx="755" ury="705"/>
<char name="a118" width="791" llx="35" lly="-13" urx="761" ury="705"/>
<char name="a117" width="690" llx="34" lly="138" urx="655" ury="553"/>
<char name="a11" width="960" llx="35" lly="123" urx="925" ury="568"/>
<char name="a12" width="939" llx="35" lly="134" urx="904" ury="559"/>
<char name="a13" width="549" llx="29" lly="-11" urx="516" ury="705"/>
<char name="a14" width="855" llx="34" lly="59" urx="820" ury="632"/>
<char name="a15" width="911" llx="35" lly="50" urx="876" ury="642"/>
<char name="a16" width="933" llx="35" lly="139" urx="899" ury="550"/>
<char name="a105" width="911" llx="35" lly="50" urx="876" ury="642"/>
<char name="a17" width="945" llx="35" lly="139" urx="909" ury="553"/>
<char name="a18" width="974" llx="35" lly="104" urx="938" ury="587"/>
<char name="a19" width="755" llx="34" lly="-13" urx="721" ury="705"/>
<char name="a20" width="846" llx="36" lly="-14" urx="811" ury="705"/>
<char name="a21" width="762" llx="35" lly="0" urx="727" ury="692"/>
<char name="a22" width="761" llx="35" lly="0" urx="727" ury="692"/>
<char name="a23" width="571" llx="-1" lly="-68" urx="571" ury="661"/>
<char name="a24" width="677" llx="36" lly="-13" urx="642" ury="705"/>
<char name="a25" width="763" llx="35" lly="0" urx="728" ury="692"/>
<char name="a26" width="760" llx="35" lly="0" urx="726" ury="692"/>
<char name="a27" width="759" llx="35" lly="0" urx="725" ury="692"/>
<char name="a28" width="754" llx="35" lly="0" urx="720" ury="692"/>
<char name="a6" width="494" llx="35" lly="0" urx="460" ury="692"/>
<char name="a7" width="552" llx="35" lly="0" urx="517" ury="692"/>
<char name="a8" width="537" llx="35" lly="0" urx="503" ury="692"/>
<char name="a9" width="577" llx="35" lly="96" urx="542" ury="596"/>
<char name="a10" width="692" llx="35" lly="-14" urx="657" ury="705"/>
<char name="a29" width="786" llx="35" lly="-14" urx="751" ury="705"/>
<char name="a30" width="788" llx="35" lly="-14" urx="752" ury="705"/>
<char name="a31" width="788" llx="35" lly="-14" urx="753" ury="705"/>
<char name="a32" width="790" llx="35" lly="-14" urx="756" ury="705"/>
<char name="a33" width="793" llx="35" lly="-13" urx="759" ury="705"/>
<char name="a34" width="794" llx="35" lly="-13" urx="759" ury="705"/>
<char name="a35" width="816" llx="35" lly="-14" urx="782" ury="705"/>
<char name="a36" width="823" llx="35" lly="-14" urx="787" ury="705"/>
<char name="a37" width="789" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a38" width="841" llx="35" lly="-14" urx="807" ury="705"/>
<char name="a39" width="823" llx="35" lly="-14" urx="789" ury="705"/>
<char name="a40" width="833" llx="35" lly="-14" urx="798" ury="705"/>
<char name="a41" width="816" llx="35" lly="-13" urx="782" ury="705"/>
<char name="a42" width="831" llx="35" lly="-14" urx="796" ury="705"/>
<char name="a43" width="923" llx="35" lly="-14" urx="888" ury="705"/>
<char name="a44" width="744" llx="35" lly="0" urx="710" ury="692"/>
<char name="a45" width="723" llx="35" lly="0" urx="688" ury="692"/>
<char name="a46" width="749" llx="35" lly="0" urx="714" ury="692"/>
<char name="a47" width="790" llx="34" lly="-14" urx="756" ury="705"/>
<char name="a48" width="792" llx="35" lly="-14" urx="758" ury="705"/>
<char name="a49" width="695" llx="35" lly="-14" urx="661" ury="706"/>
<char name="a50" width="776" llx="35" lly="-6" urx="741" ury="699"/>
<char name="a51" width="768" llx="35" lly="-7" urx="734" ury="699"/>
<char name="a52" width="792" llx="35" lly="-14" urx="757" ury="705"/>
<char name="a53" width="759" llx="35" lly="0" urx="725" ury="692"/>
<char name="a54" width="707" llx="35" lly="-13" urx="672" ury="704"/>
<char name="a55" width="708" llx="35" lly="-14" urx="672" ury="705"/>
<char name="a56" width="682" llx="35" lly="-14" urx="647" ury="705"/>
<char name="a57" width="701" llx="35" lly="-14" urx="666" ury="705"/>
<char name="a58" width="826" llx="35" lly="-14" urx="791" ury="705"/>
<char name="a59" width="815" llx="35" lly="-14" urx="780" ury="705"/>
<char name="a60" width="789" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a61" width="789" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a62" width="707" llx="34" lly="-14" urx="673" ury="705"/>
<char name="a63" width="687" llx="36" lly="0" urx="651" ury="692"/>
<char name="a64" width="696" llx="35" lly="0" urx="661" ury="691"/>
<char name="a65" width="689" llx="35" lly="0" urx="655" ury="692"/>
<char name="a66" width="786" llx="34" lly="-14" urx="751" ury="705"/>
<char name="a67" width="787" llx="35" lly="-14" urx="752" ury="705"/>
<char name="a68" width="713" llx="35" lly="-14" urx="678" ury="705"/>
<char name="a69" width="791" llx="35" lly="-14" urx="756" ury="705"/>
<char name="a70" width="785" llx="36" lly="-14" urx="751" ury="705"/>
<char name="a71" width="791" llx="35" lly="-14" urx="757" ury="705"/>
<char name="a72" width="873" llx="35" lly="-14" urx="838" ury="705"/>
<char name="a73" width="761" llx="35" lly="0" urx="726" ury="692"/>
<char name="a74" width="762" llx="35" lly="0" urx="727" ury="692"/>
<char name="a203" width="762" llx="35" lly="0" urx="727" ury="692"/>
<char name="a75" width="759" llx="35" lly="0" urx="725" ury="692"/>
<char name="a204" width="759" llx="35" lly="0" urx="725" ury="692"/>
<char name="a76" width="892" llx="35" lly="0" urx="858" ury="705"/>
<char name="a77" width="892" llx="35" lly="-14" urx="858" ury="692"/>
<char name="a78" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a79" width="784" llx="35" lly="-14" urx="749" ury="705"/>
<char name="a81" width="438" llx="35" lly="-14" urx="403" ury="705"/>
<char name="a82" width="138" llx="35" lly="0" urx="104" ury="692"/>
<char name="a83" width="277" llx="35" lly="0" urx="242" ury="692"/>
<char name="a84" width="415" llx="35" lly="0" urx="380" ury="692"/>
<char name="a97" width="392" llx="35" lly="263" urx="357" ury="705"/>
<char name="a98" width="392" llx="34" lly="263" urx="357" ury="705"/>
<char name="a99" width="668" llx="35" lly="263" urx="633" ury="705"/>
<char name="a100" width="668" llx="36" lly="263" urx="634" ury="705"/>
<char name="a101" width="732" llx="35" lly="-143" urx="697" ury="806"/>
<char name="a102" width="544" llx="56" lly="-14" urx="488" ury="706"/>
<char name="a103" width="544" llx="34" lly="-14" urx="508" ury="705"/>
<char name="a104" width="910" llx="35" lly="40" urx="875" ury="651"/>
<char name="a106" width="667" llx="35" lly="-14" urx="633" ury="705"/>
<char name="a107" width="760" llx="35" lly="-14" urx="726" ury="705"/>
<char name="a108" width="760" llx="0" lly="121" urx="758" ury="569"/>
<char name="a112" width="776" llx="35" lly="0" urx="741" ury="705"/>
<char name="a111" width="595" llx="34" lly="-14" urx="560" ury="705"/>
<char name="a110" width="694" llx="35" lly="-14" urx="659" ury="705"/>
<char name="a109" width="626" llx="34" lly="0" urx="591" ury="705"/>
<char name="a120" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a121" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a122" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a123" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a124" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a125" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a126" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a127" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a128" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a129" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a130" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a131" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a132" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a133" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a134" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a135" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a136" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a137" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a138" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a139" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a140" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a141" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a142" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a143" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a144" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a145" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a146" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a147" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a148" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a149" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a150" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a151" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a152" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a153" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a154" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a155" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a156" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a157" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a158" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a159" width="788" llx="35" lly="-14" urx="754" ury="705"/>
<char name="a160" width="894" llx="35" lly="58" urx="860" ury="634"/>
<char name="a161" width="838" llx="35" lly="152" urx="803" ury="540"/>
<char name="a163" width="1016" llx="34" lly="152" urx="981" ury="540"/>
<char name="a164" width="458" llx="35" lly="-127" urx="422" ury="820"/>
<char name="a196" width="748" llx="35" lly="94" urx="698" ury="597"/>
<char name="a165" width="924" llx="35" lly="140" urx="890" ury="552"/>
<char name="a192" width="748" llx="35" lly="94" urx="698" ury="597"/>
<char name="a166" width="918" llx="35" lly="166" urx="884" ury="526"/>
<char name="a167" width="927" llx="35" lly="32" urx="892" ury="660"/>
<char name="a168" width="928" llx="35" lly="129" urx="891" ury="562"/>
<char name="a169" width="928" llx="35" lly="128" urx="893" ury="563"/>
<char name="a170" width="834" llx="35" lly="155" urx="799" ury="537"/>
<char name="a171" width="873" llx="35" lly="93" urx="838" ury="599"/>
<char name="a172" width="828" llx="35" lly="104" urx="791" ury="588"/>
<char name="a173" width="924" llx="35" lly="98" urx="889" ury="594"/>
<char name="a162" width="924" llx="35" lly="98" urx="889" ury="594"/>
<char name="a174" width="917" llx="35" lly="0" urx="882" ury="692"/>
<char name="a175" width="930" llx="35" lly="84" urx="896" ury="608"/>
<char name="a176" width="931" llx="35" lly="84" urx="896" ury="608"/>
<char name="a177" width="463" llx="35" lly="-99" urx="429" ury="791"/>
<char name="a178" width="883" llx="35" lly="71" urx="848" ury="623"/>
<char name="a179" width="836" llx="35" lly="44" urx="802" ury="648"/>
<char name="a193" width="836" llx="35" lly="44" urx="802" ury="648"/>
<char name="a180" width="867" llx="35" lly="101" urx="832" ury="591"/>
<char name="a199" width="867" llx="35" lly="101" urx="832" ury="591"/>
<char name="a181" width="696" llx="35" lly="44" urx="661" ury="648"/>
<char name="a200" width="696" llx="35" lly="44" urx="661" ury="648"/>
<char name="a182" width="874" llx="35" lly="77" urx="840" ury="619"/>
<char name="a201" width="874" llx="35" lly="73" urx="840" ury="615"/>
<char name="a183" width="760" llx="35" lly="0" urx="725" ury="692"/>
<char name="a184" width="946" llx="35" lly="160" urx="911" ury="533"/>
<char name="a197" width="771" llx="34" lly="37" urx="736" ury="655"/>
<char name="a185" width="865" llx="35" lly="207" urx="830" ury="481"/>
<char name="a194" width="771" llx="34" lly="37" urx="736" ury="655"/>
<char name="a198" width="888" llx="34" lly="-19" urx="853" ury="712"/>
<char name="a186" width="967" llx="35" lly="124" urx="932" ury="568"/>
<char name="a195" width="888" llx="34" lly="-19" urx="853" ury="712"/>
<char name="a187" width="831" llx="35" lly="113" urx="796" ury="579"/>
<char name="a188" width="873" llx="36" lly="118" urx="838" ury="578"/>
<char name="a189" width="927" llx="35" lly="150" urx="891" ury="542"/>
<char name="a190" width="970" llx="35" lly="76" urx="931" ury="616"/>
<char name="a191" width="918" llx="34" lly="99" urx="884" ury="593"/>
<char name="a86" width="410" llx="35" lly="0" urx="375" ury="692"/>
<char name="a85" width="509" llx="35" lly="0" urx="475" ury="692"/>
<char name="a95" width="334" llx="35" lly="0" urx="299" ury="692"/>
<char name="a205" width="509" llx="35" lly="0" urx="475" ury="692"/>
<char name="a89" width="390" llx="35" lly="-14" urx="356" ury="705"/>
<char name="a87" width="234" llx="35" lly="-14" urx="199" ury="705"/>
<char name="a91" width="276" llx="35" lly="0" urx="242" ury="692"/>
<char name="a90" width="390" llx="35" lly="-14" urx="355" ury="705"/>
<char name="a206" width="410" llx="35" lly="0" urx="375" ury="692"/>
<char name="a94" width="317" llx="35" lly="0" urx="283" ury="692"/>
<char name="a93" width="317" llx="35" lly="0" urx="283" ury="692"/>
<char name="a92" width="276" llx="35" lly="0" urx="242" ury="692"/>
<char name="a96" width="334" llx="35" lly="0" urx="299" ury="692"/>
<char name="a88" width="234" llx="35" lly="-14" urx="199" ury="705"/>
</char-metrics>
</font-metrics>

+ 23
- 3
src/codegen/fonts/font-file.xsl View File

@@ -35,6 +35,7 @@
<xsl:template match="font-metrics">
package org.apache.fop.fonts.base14;

import java.awt.Rectangle;
<xsl:if test="count(kerning) &gt; 0">
import java.util.Map;
</xsl:if>
@@ -42,12 +43,14 @@ import java.util.Set;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.Base14Font;
import org.apache.fop.fonts.CodePointMapping;
import org.apache.fop.fonts.Typeface;;
import org.apache.fop.fonts.Typeface;

public class <xsl:value-of select="class-name"/> extends Base14Font {
private final static String fontName = "<xsl:value-of select="font-name"/>";
private final static String fullName = "<xsl:value-of select="full-name"/>";
private final static Set familyNames;
private final static int underlinePosition = <xsl:value-of select="underline-position"/>;
private final static int underlineThickness = <xsl:value-of select="underline-thickness"/>;
private final static String encoding = "<xsl:value-of select="$encoding"/>";
private final static int capHeight = <xsl:value-of select="cap-height"/>;
private final static int xHeight = <xsl:value-of select="x-height"/>;
@@ -56,6 +59,7 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {
private final static int firstChar = <xsl:value-of select="first-char"/>;
private final static int lastChar = <xsl:value-of select="last-char"/>;
private final static int[] width;
private final static Rectangle[] boundingBoxes;
private final CodePointMapping mapping =
CodePointMapping.getMapping("<xsl:value-of select="$encoding"/>");
<xsl:if test="count(kerning) &gt; 0">
@@ -66,7 +70,8 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {

static {
width = new int[256];
<xsl:apply-templates select="widths"/>
boundingBoxes = new Rectangle[256];
<xsl:apply-templates select="char-metrics"/>
<xsl:if test="count(kerning) &gt; 0">
kerning = new java.util.HashMap();
Integer first, second;
@@ -125,6 +130,14 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {
return size * xHeight;
}

public int getUnderlinePosition(int size) {
return size * underlinePosition;
}

public int getUnderlineThickness(int size) {
return size * underlineThickness;
}

public int getFirstChar() {
return firstChar;
}
@@ -137,6 +150,11 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {
return size * width[i];
}

public Rectangle getBoundingBox(int glyphIndex, int size) {
Rectangle bbox = boundingBoxes[glyphIndex];
return new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size);
}

public int[] getWidths() {
int[] arr = new int[getLastChar() - getFirstChar() + 1];
System.arraycopy(width, getFirstChar(), arr, 0, getLastChar() - getFirstChar() + 1);
@@ -182,7 +200,9 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {
}
</xsl:template>

<xsl:template match="widths/char"><xsl:variable name="char-name" select="@name"/><xsl:variable name="char-num" select="$glyphs[@name = $char-name]/@codepoint"/><xsl:if test="$char-num!=''"> width[0x<xsl:value-of select="$char-num"/>] = <xsl:value-of select="@width"/>;</xsl:if></xsl:template>
<xsl:template match="char-metrics/char">
<xsl:variable name="char-name" select="@name"/><xsl:variable name="char-num" select="$glyphs[@name = $char-name]/@codepoint"/><xsl:if test="$char-num!=''"> width[0x<xsl:value-of select="$char-num"/>] = <xsl:value-of select="@width"/>;
boundingBoxes[0x<xsl:value-of select="$char-num"/>] = new Rectangle(<xsl:value-of select="@llx"/>,<xsl:value-of select="@lly"/>,<xsl:value-of select="@urx - @llx"/>,<xsl:value-of select="@ury - @lly"/>);</xsl:if></xsl:template>
<xsl:template match="kerning">
first = new Integer(<xsl:value-of select="@kpx1"/>);

+ 8
- 0
src/java/org/apache/fop/afp/AFPEventProducer.java View File

@@ -122,4 +122,12 @@ public interface AFPEventProducer extends EventProducer {
* @event.severity WARN
*/
void charactersetMissingMetrics(Object source, char character, String charSet);

/**
* Double-byte fonts are not currently supported in SVG.
* @param source the event source
* @param fontFamily name of DB font
* @event.severity WARN
*/
void invalidDBFontInSVG(Object source, String fontFamily);
}

+ 31
- 1
src/java/org/apache/fop/afp/fonts/AFPFont.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.afp.fonts;

import java.awt.Rectangle;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -34,6 +35,8 @@ import org.apache.fop.fonts.Typeface;
*/
public abstract class AFPFont extends Typeface {

private static final double STRIKEOUT_POSITION_FACTOR = 0.45;

/** The font name */
protected final String name;

@@ -117,7 +120,34 @@ public abstract class AFPFont extends Typeface {
*/
protected static final char toUnicodeCodepoint(int character) {
//AFP fonts use Unicode directly as their mapped code points, so we can simply cast to char
return (char)character;
return (char) character;
}

/** {@inheritDoc} */
public int getUnderlineThickness(int size) {
// This is the FOCA recommendation in the absence of the Underline Thickness parameter
return getBoundingBox('-', size).height;
}

/** {@inheritDoc} */
public int getStrikeoutPosition(int size) {
//TODO This conflicts with the FOCA recommendation of 0 in the absence of the Throughscore Position
// parameter
return (int) (STRIKEOUT_POSITION_FACTOR * getCapHeight(size));
}

/** {@inheritDoc} */
public int getStrikeoutThickness(int size) {
// This is the FOCA recommendation in the absence of the Throughscore Thickness parameter
return getBoundingBox('-', size).height;
}

/** {@inheritDoc} */
public abstract Rectangle getBoundingBox(int glyphIndex, int size);

/** {@inheritDoc} */
public int[] getWidths() {
throw new UnsupportedOperationException();
}

/** {@inheritDoc} */

+ 11
- 49
src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java View File

@@ -70,22 +70,6 @@ public abstract class AbstractOutlineFont extends AFPFont {
return charSet;
}

/**
* Get the first character in this font.
* @return the first character in this font
*/
public int getFirstChar() {
return charSet.getFirstChar();
}

/**
* Get the last character in this font.
* @return the last character in this font
*/
public int getLastChar() {
return charSet.getLastChar();
}

/**
* The ascender is the part of a lowercase letter that extends above the
* "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also
@@ -98,6 +82,17 @@ public abstract class AbstractOutlineFont extends AFPFont {
return charSet.getAscender() * size;
}

/** {@inheritDoc} */
public int getUnderlinePosition(int size) {
return charSet.getUnderscorePosition() * size;
}

@Override
public int getUnderlineThickness(int size) {
int underscoreWidth = charSet.getUnderscoreWidth();
return underscoreWidth == 0 ? super.getUnderlineThickness(size) : underscoreWidth * size;
}

/**
* Obtains the height of capital letters for the specified point size.
*
@@ -130,40 +125,7 @@ public abstract class AbstractOutlineFont extends AFPFont {
return charSet.getXHeight() * size;
}

/**
* Obtain the width of the character for the specified point size.
* @param character the character
* @param size the font size (in mpt)
* @return the width of the character for the specified point size
*/
public int getWidth(int character, int size) {
return charSet.getWidth(toUnicodeCodepoint(character)) * size;
}

/**
* Get the getWidth (in 1/1000ths of a point size) of all characters in this
* character set.
*
* @param size the font size (in mpt)
* @return the widths of all characters
*/
public int[] getWidths(int size) {
int[] widths = charSet.getWidths();
for (int i = 0; i < widths.length; i++) {
widths[i] = widths[i] * size;
}
return widths;
}

/**
* Get the getWidth (in 1/1000ths of a point size) of all characters in this
* character set.
*
* @return the widths of all characters
*/
public int[] getWidths() {
return getWidths(1000);
}

/** {@inheritDoc} */
public boolean hasChar(char c) {

+ 27
- 45
src/java/org/apache/fop/afp/fonts/CharacterSet.java View File

@@ -19,10 +19,9 @@

package org.apache.fop.afp.fonts;

import java.awt.Rectangle;
import java.io.UnsupportedEncodingException;
import java.nio.charset.CharacterCodingException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -63,6 +62,8 @@ public class CharacterSet {

private static final int MAX_NAME_LEN = 8;

/** The current orientation (currently only 0 is supported by FOP) */
public static final int SUPPORTED_ORIENTATION = 0;

/** The code page to which the character set relates */
protected final String codePage;
@@ -79,11 +80,8 @@ public class CharacterSet {
/** The path to the installed fonts */
private final AFPResourceAccessor accessor;

/** The current orientation (currently only 0 is supported by FOP) */
private final String currentOrientation = "0";

/** The collection of objects for each orientation */
private final Map<String, CharacterSetOrientation> characterSetOrientations;
private CharacterSetOrientation characterSetOrientation;

/** The nominal vertical size (in millipoints) for bitmap fonts. 0 for outline fonts. */
private int nominalVerticalSize;
@@ -116,8 +114,6 @@ public class CharacterSet {
this.encoding = encoding;
this.encoder = charsetType.getEncoder(encoding);
this.accessor = accessor;

this.characterSetOrientations = new HashMap<String, CharacterSetOrientation>(4);
}

// right pad short names with space
@@ -131,7 +127,9 @@ public class CharacterSet {
* @param cso the metrics for the orientation
*/
public void addCharacterSetOrientation(CharacterSetOrientation cso) {
characterSetOrientations.put(String.valueOf(cso.getOrientation()), cso);
if (cso.getOrientation() == SUPPORTED_ORIENTATION) {
characterSetOrientation = cso;
}
}

/**
@@ -165,10 +163,23 @@ public class CharacterSet {
* @return the ascender value in millipoints
*/
public int getAscender() {

return getCharacterSetOrientation().getAscender();
}

/**
* TODO
*/
public int getUnderscoreWidth() {
return getCharacterSetOrientation().getUnderscoreWidth();
}

/**
* TODO
*/
public int getUnderscorePosition() {
return getCharacterSetOrientation().getUnderscorePosition();
}

/**
* Cap height is the average height of the uppercase characters in
* a font. This value is specified by the designer of a font and is
@@ -177,7 +188,6 @@ public class CharacterSet {
* @return the cap height value in millipoints
*/
public int getCapHeight() {

return getCharacterSetOrientation().getCapHeight();
}

@@ -193,24 +203,6 @@ public class CharacterSet {
return getCharacterSetOrientation().getDescender();
}

/**
* Returns the first character in the character set
*
* @return the first character in the character set (Unicode codepoint)
*/
public char getFirstChar() {
return getCharacterSetOrientation().getFirstChar();
}

/**
* Returns the last character in the character set
*
* @return the last character in the character set (Unicode codepoint)
*/
public char getLastChar() {
return getCharacterSetOrientation().getLastChar();
}

/**
* Returns the resource accessor to load the font resources with.
* @return the resource accessor to load the font resources with
@@ -219,16 +211,6 @@ public class CharacterSet {
return this.accessor;
}

/**
* Get the width (in 1/1000ths of a point size) of all characters
*
* @return the widths of all characters
*/
public int[] getWidths() {

return getCharacterSetOrientation().getWidths();
}

/**
* XHeight refers to the height of the lower case letters above the baseline.
*
@@ -246,11 +228,13 @@ public class CharacterSet {
* @param character the Unicode character from which the width will be calculated
* @return the width of the character
*/
public int getWidth(char character) {
return getCharacterSetOrientation().getWidth(character);
public int getWidth(char character, int size) {
return getCharacterSetOrientation().getWidth(character, size);
}


public Rectangle getCharacterBox(char character, int size) {
return getCharacterSetOrientation().getCharacterBox(character, size);
}

/**
* Returns the AFP character set identifier
@@ -309,9 +293,7 @@ public class CharacterSet {
* @return characterSetOrentation The current orientation metrics.
*/
private CharacterSetOrientation getCharacterSetOrientation() {
CharacterSetOrientation c
= characterSetOrientations.get(currentOrientation);
return c;
return characterSetOrientation;
}

/**

+ 41
- 54
src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.afp.fonts;

import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -292,16 +293,14 @@ public abstract class CharacterSetBuilder {
metricNormalizationFactor = 1000.0d * 72000.0d
/ fontDescriptor.getNominalFontSizeInMillipoints() / dpi;
}
ValueNormalizer normalizer = new ValueNormalizer(metricNormalizationFactor);
//process D3AC89 Font Position
processFontPosition(structuredFieldReader, characterSetOrientations,
metricNormalizationFactor);

processFontPosition(structuredFieldReader, characterSetOrientations, normalizer);
//process D38C89 Font Index (per orientation)
for (int i = 0; i < characterSetOrientations.length; i++) {
processFontIndex(structuredFieldReader,
characterSetOrientations[i], codePage, metricNormalizationFactor);
characterSet.addCharacterSetOrientation(characterSetOrientations[i]);
CharacterSetOrientation characterSetOrientation = characterSetOrientations[i];
processFontIndex(structuredFieldReader, characterSetOrientation, codePage, normalizer);
characterSet.addCharacterSetOrientation(characterSetOrientation);
}
} else {
throw new IOException("Missing D3AE89 Font Control structured field.");
@@ -314,6 +313,19 @@ public abstract class CharacterSetBuilder {
return characterSet;
}

private static class ValueNormalizer {

private final double factor;

public ValueNormalizer(double factor) {
this.factor = factor;
}

public int normalize(int value) {
return (int) Math.round(value * factor);
}
}

/**
* Load the code page information from the appropriate file. The file name
* to load is determined by the code page name and the file extension 'CDP'.
@@ -475,7 +487,7 @@ public abstract class CharacterSetBuilder {
* @throws IOException if an I/O exception of some sort has occurred.
*/
private void processFontPosition(StructuredFieldReader structuredFieldReader,
CharacterSetOrientation[] characterSetOrientations, double metricNormalizationFactor)
CharacterSetOrientation[] characterSetOrientations, ValueNormalizer normalizer)
throws IOException {

byte[] data = structuredFieldReader.getNext(FONT_POSITION_SF);
@@ -493,48 +505,34 @@ public abstract class CharacterSetBuilder {
if (position == 9) {
CharacterSetOrientation characterSetOrientation
= characterSetOrientations[characterSetOrientationIndex];

int xHeight = getSBIN(fpData, 2);
int capHeight = getSBIN(fpData, 4);
int ascHeight = getSBIN(fpData, 6);
int dscHeight = getSBIN(fpData, 8);

dscHeight = dscHeight * -1;

characterSetOrientation.setXHeight(
(int)Math.round(xHeight * metricNormalizationFactor));
characterSetOrientation.setCapHeight(
(int)Math.round(capHeight * metricNormalizationFactor));
characterSetOrientation.setAscender(
(int)Math.round(ascHeight * metricNormalizationFactor));
characterSetOrientation.setDescender(
(int)Math.round(dscHeight * metricNormalizationFactor));
int underscoreWidth = getUBIN(fpData, 17);
int underscorePosition = getSBIN(fpData, 20);
characterSetOrientation.setXHeight(normalizer.normalize(xHeight));
characterSetOrientation.setCapHeight(normalizer.normalize(capHeight));
characterSetOrientation.setAscender(normalizer.normalize(ascHeight));
characterSetOrientation.setDescender(normalizer.normalize(dscHeight));
characterSetOrientation.setUnderscoreWidth(normalizer.normalize(underscoreWidth));
characterSetOrientation.setUnderscorePosition(normalizer.normalize(underscorePosition));
}
} else if (position == 22) {
position = 0;
characterSetOrientationIndex++;
fpData[position] = data[index];
}

position++;
}

}

/**
* Process the font index details for the character set orientation.
*
* @param structuredFieldReader the structured field reader
* @param cso the CharacterSetOrientation object to populate
* @param codepage the map of code pages
* @param metricNormalizationFactor factor to apply to the metrics to get normalized
* font metric values
* @throws IOException if an I/O exception of some sort has occurred.
*/
private void processFontIndex(StructuredFieldReader structuredFieldReader,
CharacterSetOrientation cso, Map<String, String> codepage,
double metricNormalizationFactor)
throws IOException {

private void processFontIndex(StructuredFieldReader structuredFieldReader, CharacterSetOrientation cso,
Map<String, String> codepage, ValueNormalizer normalizer)
throws IOException {

byte[] data = structuredFieldReader.getNext(FONT_INDEX_SF);

@@ -543,8 +541,6 @@ public abstract class CharacterSetBuilder {
byte[] gcgid = new byte[8];
byte[] fiData = new byte[20];

char lowest = 255;
char highest = 0;
String firstABCMismatch = null;

// Read data, ignoring bytes 0 - 2
@@ -569,13 +565,15 @@ public abstract class CharacterSetBuilder {

char cidx = idx.charAt(0);
int width = getUBIN(fiData, 0);
int ascendHt = getSBIN(fiData, 2);
int descendDp = getSBIN(fiData, 4);
int a = getSBIN(fiData, 10);
int b = getUBIN(fiData, 12);
int c = getSBIN(fiData, 14);
int abc = a + b + c;
int diff = Math.abs(abc - width);
if (diff != 0 && width != 0) {
double diffPercent = 100 * diff / (double)width;
double diffPercent = 100 * diff / (double) width;
if (diffPercent > 2) {
if (LOG.isTraceEnabled()) {
LOG.trace(gcgiString + ": "
@@ -587,27 +585,16 @@ public abstract class CharacterSetBuilder {
}
}
}

if (cidx < lowest) {
lowest = cidx;
}

if (cidx > highest) {
highest = cidx;
}

int normalizedWidth = (int)Math.round(width * metricNormalizationFactor);

cso.setWidth(cidx, normalizedWidth);

int normalizedWidth = normalizer.normalize(width);
int x0 = normalizer.normalize(a);
int y0 = normalizer.normalize(-descendDp);
int dx = normalizer.normalize(b);
int dy = normalizer.normalize(ascendHt + descendDp);
cso.setCharacterMetrics(cidx, normalizedWidth, new Rectangle(x0, y0, dx, dy));
}

}
}

cso.setFirstChar(lowest);
cso.setLastChar(highest);

if (LOG.isDebugEnabled() && firstABCMismatch != null) {
//Debug level because it usually is no problem.
LOG.debug("Font has metrics inconsitencies where A+B+C doesn't equal the"

+ 66
- 58
src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java View File

@@ -19,7 +19,7 @@

package org.apache.fop.afp.fonts;

import java.util.Arrays;
import java.awt.Rectangle;

/**
* The IBM Font Object Content Architecture (FOCA) supports presentation
@@ -60,23 +60,13 @@ public class CharacterSetOrientation {
/**
* The character widths in the character set (indexed using Unicode codepoints)
*/
private int[] charsWidths;
private IntegerKeyStore<CharacterMetrics> characterMetrics;

/**
* The height of lowercase letters
*/
private int xHeight;

/**
* The first character (Unicode codepoint)
*/
private char firstChar;

/**
* The last character (Unicode codepoint)
*/
private char lastChar;

/** The character set orientation */
private final int orientation;
/** space increment */
@@ -86,6 +76,10 @@ public class CharacterSetOrientation {
/** Nominal Character Increment */
private final int nomCharIncrement;

private int underscoreWidth;

private int underscorePosition;

/**
* Constructor for the CharacterSetOrientation, the orientation is
* expressed as the degrees rotation (i.e 0, 90, 180, 270)
@@ -97,8 +91,7 @@ public class CharacterSetOrientation {
this.spaceIncrement = spaceIncrement;
this.emSpaceIncrement = emSpaceIncrement;
this.nomCharIncrement = nomCharIncrement;
charsWidths = new int[256];
Arrays.fill(charsWidths, -1);
this.characterMetrics = new IntegerKeyStore<CharacterMetrics>();
}

/**
@@ -138,19 +131,17 @@ public class CharacterSetOrientation {
}

/**
* The first character in the character set
* @return the first character (Unicode codepoint)
* TODO
*/
public char getFirstChar() {
return firstChar;
public int getUnderscoreWidth() {
return underscoreWidth;
}

/**
* The last character in the character set
* @return the last character (Unicode codepoint)
* TODO
*/
public char getLastChar() {
return lastChar;
public int getUnderscorePosition() {
return underscorePosition;
}

/**
@@ -161,17 +152,6 @@ public class CharacterSetOrientation {
return orientation;
}

/**
* Get the width (in 1/1000ths of a point size) of all characters
* in this character set.
* @return the widths of all characters
*/
public int[] getWidths() {
int[] arr = new int[(getLastChar() - getFirstChar()) + 1];
System.arraycopy(charsWidths, getFirstChar(), arr, 0, (getLastChar() - getFirstChar()) + 1);
return arr;
}

/**
* XHeight refers to the height of the lower case letters above
* the baseline.
@@ -187,13 +167,38 @@ public class CharacterSetOrientation {
* @param character the Unicode character to evaluate
* @return the widths of the character
*/
public int getWidth(char character) {
if (character >= charsWidths.length) {
throw new IllegalArgumentException("Invalid character: "
+ character + " (" + Integer.toString(character)
+ "), maximum is " + (charsWidths.length - 1));
public int getWidth(char character, int size) {
CharacterMetrics cm = getCharacterMetrics(character);
return cm == null ? -1 : size * cm.width;
}

private CharacterMetrics getCharacterMetrics(char character) {
return characterMetrics.get((int) character);
}

/**
* Get the character box (rectangle with dimensions in 1/1000ths of a point size) of the character
* identified by the parameter passed.
* @param character the Unicode character to evaluate
* @return the character box
*/
public Rectangle getCharacterBox(char character, int size) {
CharacterMetrics cm = getCharacterMetrics(character);
return scale(cm == null ? getFallbackCharacterBox() : cm.characterBox, size);
}

private static Rectangle scale(Rectangle rectangle, int size) {
if (rectangle == null) {
return null;
} else {
return new Rectangle((int) (size * rectangle.getX()), (int) (size * rectangle.getY()),
(int) (size * rectangle.getWidth()), (int) (size * rectangle.getHeight()));
}
return charsWidths[character];
}

private Rectangle getFallbackCharacterBox() {
// TODO replace with something sensible
return new Rectangle(0, 0, 0, 0);
}

/**
@@ -233,19 +238,19 @@ public class CharacterSetOrientation {
}

/**
* The first character in the character set
* @param firstChar the first character
* TODO
* @param underscoreWidth the underscore width value in millipoints
*/
public void setFirstChar(char firstChar) {
this.firstChar = firstChar;
public void setUnderscoreWidth(int underscoreWidth) {
this.underscoreWidth = underscoreWidth;
}

/**
* The last character in the character set
* @param lastChar the last character
* TODO
* @param underscorePosition the underscore position value in millipoints
*/
public void setLastChar(char lastChar) {
this.lastChar = lastChar;
public void setUnderscorePosition(int underscorePosition) {
this.underscorePosition = underscorePosition;
}

/**
@@ -254,17 +259,8 @@ public class CharacterSetOrientation {
* @param character the Unicode character for which the width is being set
* @param width the widths of the character
*/
public void setWidth(char character, int width) {
if (character >= charsWidths.length) {
// Increase the size of the array if necessary
// TODO Can we remove firstChar? surely firstChar==0 at this stage?
int[] arr = new int[(character - firstChar) + 1];
System.arraycopy(charsWidths, 0, arr, 0, charsWidths.length);
Arrays.fill(arr, charsWidths.length, character - firstChar, -1);
charsWidths = arr;
}
charsWidths[character] = width;

public void setCharacterMetrics(char character, int width, Rectangle characterBox) {
characterMetrics.put((int) character, new CharacterMetrics(width, characterBox));
}

/**
@@ -299,4 +295,16 @@ public class CharacterSetOrientation {
public int getNominalCharIncrement() {
return this.nomCharIncrement;
}

private static class CharacterMetrics {

public final int width;

public final Rectangle characterBox;

public CharacterMetrics(int width, Rectangle characterBox) {
this.width = width;
this.characterBox = characterBox;
}
}
}

+ 31
- 3
src/java/org/apache/fop/afp/fonts/DoubleByteFont.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.afp.fonts;

import java.awt.Rectangle;
import java.lang.Character.UnicodeBlock;
import java.util.HashSet;
import java.util.Set;
@@ -68,7 +69,7 @@ public class DoubleByteFont extends AbstractOutlineFont {
public int getWidth(int character, int size) {
int charWidth;
try {
charWidth = charSet.getWidth(toUnicodeCodepoint(character));
charWidth = charSet.getWidth(toUnicodeCodepoint(character), size);
} catch (IllegalArgumentException e) {
if (!charsProcessed.contains(character)) {
charsProcessed.add(character);
@@ -80,9 +81,9 @@ public class DoubleByteFont extends AbstractOutlineFont {
}

if (charWidth == -1) {
charWidth = getDefaultCharacterWidth(character);
charWidth = getDefaultCharacterWidth(character) * size;
}
return charWidth * size;
return charWidth;
}

private int getDefaultCharacterWidth(int character) {
@@ -94,6 +95,33 @@ public class DoubleByteFont extends AbstractOutlineFont {
}
}

@Override
public Rectangle getBoundingBox(int character, int size) {
Rectangle characterBox = getBoundingBoxOrNull(character, size);
if (characterBox == null) {
characterBox = getDefaultCharacterBox(character, size);
}
return characterBox;
}

private Rectangle getBoundingBoxOrNull(int character, int size) {
Rectangle characterBox = null;
try {
characterBox = charSet.getCharacterBox(toUnicodeCodepoint(character), size);
} catch (IllegalArgumentException e) {
if (!charsProcessed.contains(character)) {
charsProcessed.add(character);
getAFPEventProducer().charactersetMissingMetrics(this, (char) character,
charSet.getName().trim());
}
}
return characterBox;
}

private Rectangle getDefaultCharacterBox(int character, int size) {
return getBoundingBoxOrNull('-', size);
}

private int inferCharWidth(int character) {

//Is this character an ideograph?

+ 19
- 31
src/java/org/apache/fop/afp/fonts/FopCharacterSet.java View File

@@ -19,6 +19,8 @@

package org.apache.fop.afp.fonts;

import java.awt.Rectangle;

import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.fonts.Typeface;
@@ -84,45 +86,31 @@ public class FopCharacterSet extends CharacterSet {
}

/**
* The first character in the character set
* @return the first character
* XHeight refers to the height of the lower case letters above the baseline.
* @return the typical height of characters
*/
public char getFirstChar() {
return 0;
public int getXHeight() {
return charSet.getXHeight(1);
}

/**
* The last character in the character set
* @return the last character
*/
public char getLastChar() {
return 0;
@Override
public int getWidth(char character, int size) {
return charSet.getWidth(character, size);
}

/**
* Get the width (in 1/1000ths of a point size) of all characters
* @return the widths of all characters
*/
public int[] getWidths() {
return charSet.getWidths();
}
@Override
public Rectangle getCharacterBox(char character, int size) {
return charSet.getBoundingBox(character, size);
};

/**
* XHeight refers to the height of the lower case letters above the baseline.
* @return the typical height of characters
*/
public int getXHeight() {
return charSet.getXHeight(1);
@Override
public int getUnderscoreWidth() {
return charSet.getUnderlineThickness(1);
}

/**
* Get the width (in 1/1000ths of a point size) of the character
* identified by the parameter passed.
* @param character the character from which the width will be calculated
* @return the width of the character
*/
public int getWidth(char character) {
return charSet.getWidth(character, 1);
@Override
public int getUnderscorePosition() {
return charSet.getUnderlinePosition(1);
}

/**

+ 71
- 0
src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java View File

@@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.afp.fonts;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
* A simple compact data structure to model a sparse array
*/
class IntegerKeyStore<T> {

private static final int RANGE_BIT_SIZE = 8;

private static final int RANGE_SIZE = 1 << RANGE_BIT_SIZE;

private final Map<Integer, ArrayList<T>> arrays = new HashMap<Integer, ArrayList<T>>();

/**
*
* @param index a positive integer
* @param value value to store
*/
public void put(Integer index, T value) {
if (index < 0) {
throw new IndexOutOfBoundsException();
}
int rangeKey = index >> RANGE_BIT_SIZE;
int rangeIndex = index % RANGE_SIZE;
ArrayList<T> range = arrays.get(rangeKey);
if (range == null) {
range = new ArrayList<T>(Collections.<T>nCopies(RANGE_SIZE, null));
arrays.put(rangeKey, range);
}
range.set(rangeIndex, value);
}

/**
*
* @param index a positive integer
* @return value the value associated with the index or null
*/
public T get(Integer index) {
if (index < 0) {
throw new IndexOutOfBoundsException();
}
int rangeKey = index >> RANGE_BIT_SIZE;
int rangeIndex = index % RANGE_SIZE;
ArrayList<T> range = arrays.get(rangeKey);
return range == null ? null : range.get(rangeIndex);
}
}

+ 16
- 0
src/java/org/apache/fop/afp/fonts/OutlineFont.java View File

@@ -19,6 +19,8 @@

package org.apache.fop.afp.fonts;

import java.awt.Rectangle;

import org.apache.fop.afp.AFPEventProducer;

/**
@@ -38,4 +40,18 @@ public class OutlineFont extends AbstractOutlineFont {
super(name, embeddable, charSet, eventProducer);
}

/**
* Obtain the width of the character for the specified point size.
* @param character the character
* @param size the font size (in mpt)
* @return the width of the character for the specified point size
*/
public int getWidth(int character, int size) {
return charSet.getWidth(toUnicodeCodepoint(character), size);
}

@Override
public Rectangle getBoundingBox(int character, int size) {
return charSet.getCharacterBox(toUnicodeCodepoint(character), size);
}
}

+ 32
- 56
src/java/org/apache/fop/afp/fonts/RasterFont.java View File

@@ -19,8 +19,8 @@

package org.apache.fop.afp.fonts;

import java.awt.Rectangle;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -135,46 +135,21 @@ public class RasterFont extends AFPFont {

}

/**
* Get the first character in this font.
* @return the first character in this font.
*/
public int getFirstChar() {
Iterator<CharacterSet> it = charSets.values().iterator();
if (it.hasNext()) {
CharacterSet csm = it.next();
return csm.getFirstChar();
} else {
String msg = "getFirstChar() - No character set found for font:" + getFontName();
LOG.error(msg);
throw new FontRuntimeException(msg);
}
}

/**
* Get the last character in this font.
* @return the last character in this font.
*/
public int getLastChar() {

Iterator<CharacterSet> it = charSets.values().iterator();
if (it.hasNext()) {
CharacterSet csm = it.next();
return csm.getLastChar();
private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) {
int nominalVerticalSize = cs.getNominalVerticalSize();
if (nominalVerticalSize != 0) {
return value * nominalVerticalSize;
} else {
String msg = "getLastChar() - No character set found for font:" + getFontName();
LOG.error(msg);
throw new FontRuntimeException(msg);
return value * givenSize;
}

}

private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) {
private int metricsToAbsoluteSize(CharacterSet cs, double value, int givenSize) {
int nominalVerticalSize = cs.getNominalVerticalSize();
if (nominalVerticalSize != 0) {
return value * nominalVerticalSize;
return (int) (value * nominalVerticalSize);
} else {
return value * givenSize;
return (int) (value * givenSize);
}
}

@@ -191,6 +166,20 @@ public class RasterFont extends AFPFont {
return metricsToAbsoluteSize(cs, cs.getAscender(), size);
}

/** {@inheritDoc} */
public int getUnderlinePosition(int size) {
CharacterSet cs = getCharacterSet(size);
return metricsToAbsoluteSize(cs, cs.getUnderscorePosition(), size);
}

@Override
public int getUnderlineThickness(int size) {
CharacterSet cs = getCharacterSet(size);
int underscoreWidth = cs.getUnderscoreWidth();
return underscoreWidth == 0 ? super.getUnderlineThickness(size)
: metricsToAbsoluteSize(cs, underscoreWidth, size);
}

/**
* Obtains the height of capital letters for the specified point size.
*
@@ -234,33 +223,20 @@ public class RasterFont extends AFPFont {
*/
public int getWidth(int character, int size) {
CharacterSet cs = getCharacterSet(size);
return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character)), size);
return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character), 1), size);
}

/**
* Get the getWidth (in 1/1000ths of a point size) of all characters in this
* character set.
*
* @param size the font size (in mpt)
* @return the widths of all characters
* TODO
*/
public int[] getWidths(int size) {
public Rectangle getBoundingBox(int character, int size) {
CharacterSet cs = getCharacterSet(size);
int[] widths = cs.getWidths();
for (int i = 0, c = widths.length; i < c; i++) {
widths[i] = metricsToAbsoluteSize(cs, widths[i], size);
}
return widths;
}

/**
* Get the getWidth (in 1/1000ths of a point size) of all characters in this
* character set.
*
* @return the widths of all characters
*/
public int[] getWidths() {
return getWidths(1000);
Rectangle characterBox = cs.getCharacterBox(toUnicodeCodepoint(character), 1);
int x = metricsToAbsoluteSize(cs, characterBox.getX(), size);
int y = metricsToAbsoluteSize(cs, characterBox.getY(), size);
int w = metricsToAbsoluteSize(cs, characterBox.getWidth(), size);
int h = metricsToAbsoluteSize(cs, characterBox.getHeight(), size);
return new Rectangle(x, y, w, h);
}

/** {@inheritDoc} */

+ 5
- 1
src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java View File

@@ -67,7 +67,11 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord {

/** {@inheritDoc} */
public int getDataLength() {
return super.getDataLength() + str.length();
try {
return super.getDataLength() + getStringAsBytes().length;
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}

/** {@inheritDoc} */

+ 18
- 24
src/java/org/apache/fop/afp/svg/AFPBridgeContext.java View File

@@ -25,13 +25,17 @@ import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.gvt.TextPainter;
import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
import org.apache.batik.gvt.font.FontFamilyResolver;

import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;

import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.AbstractFOPBridgeContext;
import org.apache.fop.svg.font.AggregatingFontFamilyResolver;

/**
* An AFP specific implementation of a Batik BridgeContext
@@ -40,6 +44,8 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext {

private final AFPGraphics2D g2d;

private final EventBroadcaster eventBroadCaster;

/**
* Constructs a new bridge context.
*
@@ -54,47 +60,35 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext {
*/
public AFPBridgeContext(UserAgent userAgent, FontInfo fontInfo,
ImageManager imageManager, ImageSessionContext imageSessionContext,
AffineTransform linkTransform, AFPGraphics2D g2d) {
AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) {
super(userAgent, fontInfo, imageManager, imageSessionContext, linkTransform);
this.g2d = g2d;
this.eventBroadCaster = eventBroadCaster;
}

/**
* Constructs a new bridge context.
* @param userAgent the user agent
* @param documentLoader the Document Loader to use for referenced documents.
* @param fontInfo the font list for the text painter, may be null
* in which case text is painted as shapes
* @param imageManager an image manager
* @param imageSessionContext an image session context
* @param linkTransform AffineTransform to properly place links,
* may be null
* @param g2d an AFPGraphics 2D implementation
*/
public AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
private AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
FontInfo fontInfo, ImageManager imageManager,
ImageSessionContext imageSessionContext,
AffineTransform linkTransform, AFPGraphics2D g2d) {
super(userAgent, documentLoader, fontInfo, imageManager,
imageSessionContext, linkTransform);
AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) {
super(userAgent, documentLoader, fontInfo, imageManager, imageSessionContext, linkTransform);
this.g2d = g2d;
this.eventBroadCaster = eventBroadCaster;
}

/** {@inheritDoc} */
@Override
public void registerSVGBridges() {
super.registerSVGBridges();

if (fontInfo != null) {
AFPTextHandler textHandler = new AFPTextHandler(fontInfo, g2d.getResourceManager());
g2d.setCustomTextHandler(textHandler);

TextPainter textPainter = new AFPTextPainter(textHandler);
setTextPainter(textPainter);

//TODO
FontFamilyResolver fontFamilyResolver = new AggregatingFontFamilyResolver(
new AFPFontFamilyResolver(fontInfo, eventBroadCaster), DefaultFontFamilyResolver.SINGLETON);
TextPainter textPainter = new AFPTextPainter(textHandler, fontFamilyResolver);
setTextPainter(new AFPTextPainter(textHandler, fontFamilyResolver));
putBridge(new AFPTextElementBridge(textPainter));
}

putBridge(new AFPImageElementBridge());
}

@@ -105,7 +99,7 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext {
fontInfo,
getImageManager(),
getImageSessionContext(),
linkTransform, g2d);
linkTransform, g2d, eventBroadCaster);
}

}

+ 84
- 0
src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java View File

@@ -0,0 +1,84 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.afp.svg;

import java.util.HashMap;
import java.util.Map;

import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.afp.fonts.DoubleByteFont;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
import org.apache.fop.svg.font.FOPGVTFontFamily;
import org.apache.fop.svg.font.FilteringFontFamilyResolver;

public class AFPFontFamilyResolver extends FilteringFontFamilyResolver {

private final FontInfo fontInfo;

private final AFPEventProducer eventProducer;


public AFPFontFamilyResolver(FontInfo fontInfo, EventBroadcaster eventBroadCaster) {
super(new FOPFontFamilyResolverImpl(fontInfo));
this.fontInfo = fontInfo;
this.eventProducer = AFPEventProducer.Provider.get(eventBroadCaster);
}

@Override
public FOPGVTFontFamily resolve(String familyName) {
FOPGVTFontFamily fopGVTFontFamily = super.resolve(familyName);
// TODO why don't DB fonts work with GOCA?!?
if (fopGVTFontFamily != null && fopGVTFontFamily.deriveFont(1, new HashMap())
.getFont().getFontMetrics() instanceof DoubleByteFont) {
notifyDBFontRejection(fopGVTFontFamily.getFamilyName());
fopGVTFontFamily = null;
}
return fopGVTFontFamily;
}

@Override
public FOPGVTFontFamily getFamilyThatCanDisplay(char c) {
Map<String, Typeface> fonts = fontInfo.getFonts();
for (Typeface font : fonts.values()) {
// TODO why don't DB fonts work with GOCA?!?
if (font.hasChar(c) && !(font instanceof DoubleByteFont)) {
String fontFamily = font.getFamilyNames().iterator().next();
if (font instanceof DoubleByteFont) {
notifyDBFontRejection(font.getFontName());
} else {
return new FOPGVTFontFamily(fontInfo, fontFamily,
new FontTriplet(fontFamily, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL));
}

}
}
return null;
}

private void notifyDBFontRejection(String fontFamily) {
eventProducer.invalidDBFontInSVG(this, fontFamily);
}

}

+ 11
- 20
src/java/org/apache/fop/afp/svg/AFPTextHandler.java View File

@@ -135,27 +135,18 @@ public class AFPTextHandler extends FOPTextHandlerAdapter {
if (log.isDebugEnabled()) {
log.debug(" with overriding font: " + internalFontName + ", " + fontSize);
}
} else {
java.awt.Font awtFont = g2d.getFont();
Font fopFont = fontInfo.getFontInstanceForAWTFont(awtFont);
if (log.isDebugEnabled()) {
log.debug(" with font: " + fopFont);
}
internalFontName = fopFont.getFontName();
fontSize = fopFont.getFontSize();
fontSize = (int) Math.round(g2d.convertToAbsoluteLength(fontSize));
fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
// TODO: re-think above registerPageFont code...
AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName);
final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
// Work-around for InfoPrint's AFP which loses character set state
// over Graphics Data
// boundaries.
graphicsObj.setCharacterSet(fontReference);
// add the character string
graphicsObj.addString(str, Math.round(x), Math.round(y), charSet);
}
fontSize = (int)Math.round(
g2d.convertToAbsoluteLength(fontSize));
fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
// TODO: re-think above registerPageFont code...
AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName);
final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
// Work-around for InfoPrint's AFP which loses character set state
// over Graphics Data
// boundaries.
graphicsObj.setCharacterSet(fontReference);
// add the character string
graphicsObj.addString(str, Math.round(x), Math.round(y), charSet);
} else {
//Inside Batik's SVG filter operations, you won't get an AFPGraphics2D
g.drawString(str, x, y);

+ 19
- 2
src/java/org/apache/fop/afp/svg/AFPTextPainter.java View File

@@ -21,6 +21,9 @@ package org.apache.fop.afp.svg;

import java.awt.Graphics2D;

import org.apache.batik.gvt.font.FontFamilyResolver;
import org.apache.batik.gvt.renderer.StrokingTextPainter;

import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.svg.AbstractFOPTextPainter;
import org.apache.fop.svg.FOPTextHandler;
@@ -39,8 +42,8 @@ public class AFPTextPainter extends AbstractFOPTextPainter {
* Create a new text painter with the given font information.
* @param nativeTextHandler the NativeTextHandler instance used for text painting
*/
public AFPTextPainter(FOPTextHandler nativeTextHandler) {
super(nativeTextHandler);
public AFPTextPainter(FOPTextHandler nativeTextHandler, FontFamilyResolver fopFontFamilyResolver) {
super(nativeTextHandler, new FOPStrokingTextPainter(fopFontFamilyResolver));
}

/** {@inheritDoc} */
@@ -48,4 +51,18 @@ public class AFPTextPainter extends AbstractFOPTextPainter {
return g2d instanceof AFPGraphics2D;
}

private static class FOPStrokingTextPainter extends StrokingTextPainter {

private final FontFamilyResolver fopFontFontFamily;

FOPStrokingTextPainter(FontFamilyResolver fopFontFontFamily) {
this.fopFontFontFamily = fopFontFontFamily;
}

@Override
protected FontFamilyResolver getFontFamilyResolver() {
return fopFontFontFamily;
}
}

}

+ 2
- 92
src/java/org/apache/fop/fo/FOText.java View File

@@ -21,7 +21,6 @@ package org.apache.fop.fo;

import java.awt.Color;
import java.nio.CharBuffer;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Stack;

@@ -38,12 +37,13 @@ import org.apache.fop.fo.properties.CommonTextDecoration;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.SpaceProperty;
import org.apache.fop.fonts.TextFragment;
import org.apache.fop.util.CharUtilities;

/**
* A text node (PCDATA) in the formatting object tree.
*/
public class FOText extends FONode implements CharSequence {
public class FOText extends FONode implements CharSequence, TextFragment {

/** the <code>CharBuffer</code> containing the text */
private CharBuffer charBuffer;
@@ -93,9 +93,6 @@ public class FOText extends FONode implements CharSequence {
/* bidi levels */
private int[] bidiLevels;

/* advanced script processing state */
private Map/*<MapRange,String>*/ mappings;

private static final int IS_WORD_CHAR_FALSE = 0;
private static final int IS_WORD_CHAR_TRUE = 1;
private static final int IS_WORD_CHAR_MAYBE = 2;
@@ -804,93 +801,6 @@ public class FOText extends FONode implements CharSequence {
}
}

/**
* Add characters mapped by script substitution processing.
* @param start index in character buffer
* @param end index in character buffer
* @param mappedChars sequence of character codes denoting substituted characters
*/
public void addMapping(int start, int end, CharSequence mappedChars) {
if (mappings == null) {
mappings = new java.util.HashMap();
}
mappings.put(new MapRange(start, end), mappedChars.toString());
}

/**
* Determine if characters over specific interval have a mapping.
* @param start index in character buffer
* @param end index in character buffer
* @return true if a mapping exist such that the mapping's interval is coincident to
* [start,end)
*/
public boolean hasMapping(int start, int end) {
return (mappings != null) && (mappings.containsKey(new MapRange(start, end)));
}

/**
* Obtain mapping of characters over specific interval.
* @param start index in character buffer
* @param end index in character buffer
* @return a string of characters representing the mapping over the interval
* [start,end)
*/
public String getMapping(int start, int end) {
if (mappings != null) {
return (String) mappings.get(new MapRange(start, end));
} else {
return null;
}
}

/**
* Obtain length of mapping of characters over specific interval.
* @param start index in character buffer
* @param end index in character buffer
* @return the length of the mapping (if present) or zero
*/
public int getMappingLength(int start, int end) {
if (mappings != null) {
return ((String) mappings.get(new MapRange(start, end))) .length();
} else {
return 0;
}
}

/**
* Obtain bidirectional levels of mapping of characters over specific interval.
* @param start index in character buffer
* @param end index in character buffer
* @return a (possibly empty) array of bidi levels or null
* in case no bidi levels have been assigned
*/
public int[] getMappingBidiLevels(int start, int end) {
if (hasMapping(start, end)) {
int nc = end - start;
int nm = getMappingLength(start, end);
int[] la = getBidiLevels(start, end);
if (la == null) {
return null;
} else if (nm == nc) { // mapping is same length as mapped range
return la;
} else if (nm > nc) { // mapping is longer than mapped range
int[] ma = new int [ nm ];
System.arraycopy(la, 0, ma, 0, la.length);
for (int i = la.length,
n = ma.length, l = (i > 0) ? la [ i - 1 ] : 0; i < n; i++) {
ma [ i ] = l;
}
return ma;
} else { // mapping is shorter than mapped range
int[] ma = new int [ nm ];
System.arraycopy(la, 0, ma, 0, ma.length);
return ma;
}
} else {
return getBidiLevels(start, end);
}
}

@Override
protected Stack collectDelimitedTextRanges(Stack ranges, DelimitedTextRange currentRange) {
if (currentRange != null) {

+ 11
- 0
src/java/org/apache/fop/fonts/Base14Font.java View File

@@ -25,4 +25,15 @@ package org.apache.fop.fonts;
*/
public abstract class Base14Font extends Typeface {

/** Thickness for underline and strikeout. */
private static final int LINE_THICKNESS = 50;

public int getStrikeoutPosition(int size) {
return getXHeight(size) / 2;
}

public int getStrikeoutThickness(int size) {
return size * LINE_THICKNESS;
}

}

+ 1
- 0
src/java/org/apache/fop/fonts/CIDFont.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.fonts;


import org.apache.fop.apps.io.InternalResourceResolver;

//Java

+ 47
- 0
src/java/org/apache/fop/fonts/CustomFont.java View File

@@ -37,6 +37,9 @@ import org.apache.fop.apps.io.InternalResourceResolver;
public abstract class CustomFont extends Typeface
implements FontDescriptor, MutableFont {

/** Fallback thickness for underline and strikeout when not provided by the font. */
private static final int DEFAULT_LINE_THICKNESS = 50;

private String fontName;
private String fullName;
private Set<String> familyNames;
@@ -60,6 +63,14 @@ public abstract class CustomFont extends Typeface
private int firstChar;
private int lastChar = 255;

private int underlinePosition;

private int underlineThickness;

private int strikeoutPosition;

private int strikeoutThickness;

private Map<Integer, Map<Integer, Integer>> kerning;

private boolean useKerning = true;
@@ -507,4 +518,40 @@ public abstract class CustomFont extends Typeface
return copy;
}

public int getUnderlinePosition(int size) {
return (underlinePosition == 0)
? getDescender(size) / 2
: size * underlinePosition;
}

public void setUnderlinePosition(int underlinePosition) {
this.underlinePosition = underlinePosition;
}

public int getUnderlineThickness(int size) {
return size * ((underlineThickness == 0) ? DEFAULT_LINE_THICKNESS : underlineThickness);
}

public void setUnderlineThickness(int underlineThickness) {
this.underlineThickness = underlineThickness;
}

public int getStrikeoutPosition(int size) {
return (strikeoutPosition == 0)
? getXHeight(size) / 2
: size * strikeoutPosition;
}

public void setStrikeoutPosition(int strikeoutPosition) {
this.strikeoutPosition = strikeoutPosition;
}

public int getStrikeoutThickness(int size) {
return (strikeoutThickness == 0) ? getUnderlineThickness(size) : size * strikeoutThickness;
}

public void setStrikeoutThickness(int strikeoutThickness) {
this.strikeoutThickness = strikeoutThickness;
}

}

+ 14
- 23
src/java/org/apache/fop/fonts/FontInfo.java View File

@@ -30,6 +30,7 @@ import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
* The FontInfo holds font information for the layout and rendering of a fo document.
* This stores the list of available fonts that are setup by
@@ -135,12 +136,10 @@ public class FontInfo {
if (oldName != null) {
int oldPriority = tripletPriorities.get(triplet).intValue();
if (oldPriority < newPriority) {
logDuplicateFont(triplet, false, oldName, oldPriority,
internalFontKey, newPriority);
logDuplicateFont(triplet, false, oldName, oldPriority, internalFontKey, newPriority);
return;
} else {
logDuplicateFont(triplet, true, oldName, oldPriority,
internalFontKey, newPriority);
logDuplicateFont(triplet, true, oldName, oldPriority, internalFontKey, newPriority);
}
}
this.triplets.put(triplet, internalFontKey);
@@ -157,9 +156,8 @@ public class FontInfo {
* @param newKey the new internal font name
* @param newPriority the priority of the duplicate font mapping
*/
private void logDuplicateFont(FontTriplet triplet, boolean replacing,
String oldKey, int oldPriority,
String newKey, int newPriority) {
private void logDuplicateFont(FontTriplet triplet, boolean replacing, String oldKey, int oldPriority,
String newKey, int newPriority) {
if (log.isDebugEnabled()) {
log.debug(triplet
+ (replacing ? ": Replacing " : ": Not replacing ")
@@ -198,8 +196,7 @@ public class FontInfo {
* default font if not found
* @return internal font triplet key
*/
private FontTriplet fontLookup(String family, String style,
int weight, boolean substitutable) {
private FontTriplet fontLookup(String family, String style, int weight, boolean substitutable) {
if (log.isTraceEnabled()) {
log.trace("Font lookup: " + family + " " + style + " " + weight
+ (substitutable ? " substitutable" : ""));
@@ -302,8 +299,7 @@ public class FontInfo {
* @return the requested Font instance
*/
public Font getFontInstance(FontTriplet triplet, int fontSize) {
Map<Integer, Font> sizes
= getFontInstanceCache().get(triplet);
Map<Integer, Font> sizes = getFontInstanceCache().get(triplet);
if (sizes == null) {
sizes = new HashMap<Integer, Font>();
getFontInstanceCache().put(triplet, sizes);
@@ -379,13 +375,11 @@ public class FontInfo {
* @param weight font weight
* @return the font triplet of the font chosen
*/
public FontTriplet fontLookup(String family, String style,
int weight) {
public FontTriplet fontLookup(String family, String style, int weight) {
return fontLookup(family, style, weight, true);
}

private List<FontTriplet> fontLookup(String[] families, String style,
int weight, boolean substitutable) {
private List<FontTriplet> fontLookup(String[] families, String style, int weight, boolean substitutable) {
List<FontTriplet> matchingTriplets = new ArrayList<FontTriplet>();
FontTriplet triplet = null;
for (int i = 0; i < families.length; i++) {
@@ -410,8 +404,7 @@ public class FontInfo {
* @return the set of font triplets of all supported and chosen font-families
* in the specified style and weight.
*/
public FontTriplet[] fontLookup(String[] families, String style,
int weight) {
public FontTriplet[] fontLookup(String[] families, String style, int weight) {
if (families.length == 0) {
throw new IllegalArgumentException("Specify at least one font family");
}
@@ -434,8 +427,8 @@ public class FontInfo {
sb.append(families[i]);
}
throw new IllegalStateException(
"fontLookup must return an array with at least one "
+ "FontTriplet on the last call. Lookup: " + sb.toString());
"fontLookup must return an array with at least one "
+ "FontTriplet on the last call. Lookup: " + sb.toString());

}
FontTriplet[] fontTriplets = new FontTriplet[matchedTriplets.size()];
@@ -469,8 +462,7 @@ public class FontInfo {
* @param weight font weight
* @return internal key
*/
public FontTriplet findAdjustWeight(String family, String style,
int weight) {
public FontTriplet findAdjustWeight(String family, String style, int weight) {
FontTriplet key = null;
String f = null;
int newWeight = weight;
@@ -542,8 +534,7 @@ public class FontInfo {
* @param weight font weight
* @return internal key
*/
public static FontTriplet createFontKey(String family, String style,
int weight) {
public static FontTriplet createFontKey(String family, String style, int weight) {
return new FontTriplet(family, style, weight);
}


+ 44
- 0
src/java/org/apache/fop/fonts/FontMetrics.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.fonts;

import java.awt.Rectangle;
import java.util.Map;
import java.util.Set;

@@ -119,6 +120,15 @@ public interface FontMetrics {
*/
int[] getWidths();

/**
* Returns the bounding box of the glyph at the given index, for the given font size.
*
* @param glyphIndex glyph index
* @param size font size
* @return the scaled bounding box scaled in 1/1000ths of the given size
*/
Rectangle getBoundingBox(int glyphIndex, int size);

/**
* Indicates if the font has kering information.
* @return True, if kerning is available.
@@ -131,4 +141,38 @@ public interface FontMetrics {
*/
Map<Integer, Map<Integer, Integer>> getKerningInfo();

/**
* Returns the distance from the baseline to the center of the underline (negative
* value indicates below baseline).
*
* @param size font size
* @return the position in 1/1000ths of the font size
*/
int getUnderlinePosition(int size);

/**
* Returns the thickness of the underline.
*
* @param size font size
* @return the thickness in 1/1000ths of the font size
*/
int getUnderlineThickness(int size);

/**
* Returns the distance from the baseline to the center of the strikeout line
* (negative value indicates below baseline).
*
* @param size font size
* @return the position in 1/1000ths of the font size
*/
int getStrikeoutPosition(int size);

/**
* Returns the thickness of the strikeout line.
*
* @param size font size
* @return the thickness in 1/1000ths of the font size
*/
int getStrikeoutThickness(int size);

}

+ 327
- 0
src/java/org/apache/fop/fonts/GlyphMapping.java View File

@@ -0,0 +1,327 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.fonts;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
import org.apache.fop.complexscripts.util.CharScript;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.util.CharUtilities;

/**
* Stores the mapping of a text fragment to glyphs, along with various information.
*/
public class GlyphMapping {

private static final Log LOG = LogFactory.getLog(GlyphMapping.class);
/** Inclusive. */
public final int startIndex;
/** Exclusive. */
public final int endIndex;
private int wordCharLength;
public final int wordSpaceCount;
public int letterSpaceCount;
public MinOptMax areaIPD;
public final boolean isHyphenated;
public final boolean isSpace;
public boolean breakOppAfter;
public final Font font;
public final int level;
public final int[][] gposAdjustments;
public final String mapping;

public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount,
MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter,
Font font, int level, int[][] gposAdjustments) {
this(startIndex, endIndex, wordSpaceCount, letterSpaceCount, areaIPD, isHyphenated,
isSpace, breakOppAfter, font, level, gposAdjustments, null);
}

public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount,
MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter,
Font font, int level, int[][] gposAdjustments, String mapping) {
assert startIndex <= endIndex;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.wordCharLength = -1;
this.wordSpaceCount = wordSpaceCount;
this.letterSpaceCount = letterSpaceCount;
this.areaIPD = areaIPD;
this.isHyphenated = isHyphenated;
this.isSpace = isSpace;
this.breakOppAfter = breakOppAfter;
this.font = font;
this.level = level;
this.gposAdjustments = gposAdjustments;
this.mapping = mapping;
}

public static GlyphMapping doGlyphMapping(TextFragment text, int startIndex, int endIndex,
Font font, MinOptMax letterSpaceIPD, MinOptMax[] letterSpaceAdjustArray,
char precedingChar, char breakOpportunityChar, final boolean endsWithHyphen, int level) {
GlyphMapping mapping;
if (font.performsSubstitution() || font.performsPositioning()) {
mapping = processWordMapping(text, startIndex, endIndex, font,
breakOpportunityChar, endsWithHyphen, level);
} else {
mapping = processWordNoMapping(text, startIndex, endIndex, font,
letterSpaceIPD, letterSpaceAdjustArray, precedingChar, breakOpportunityChar, endsWithHyphen,
level);
}
return mapping;
}

private static GlyphMapping processWordMapping(TextFragment text, int startIndex,
int endIndex, final Font font, final char breakOpportunityChar,
final boolean endsWithHyphen, int level) {
int e = endIndex; // end index of word in FOText character buffer
int nLS = 0; // # of letter spaces
String script = text.getScript();
String language = text.getLanguage();

if (LOG.isDebugEnabled()) {
LOG.debug("PW: [" + startIndex + "," + endIndex + "]: {"
+ " +M"
+ ", level = " + level
+ " }");
}

// 1. extract unmapped character sequence
CharSequence ics = text.subSequence(startIndex, e);

// 2. if script is not specified (by FO property) or it is specified as 'auto',
// then compute dominant script
if ((script == null) || "auto".equals(script)) {
script = CharScript.scriptTagFromCode(CharScript.dominantScript(ics));
}
if ((language == null) || "none".equals(language)) {
language = "dflt";
}

// 3. perform mapping of chars to glyphs ... to glyphs ... to chars
CharSequence mcs = font.performSubstitution(ics, script, language);

// 4. compute glyph position adjustments on (substituted) characters
int[][] gpa;
if (font.performsPositioning()) {
// handle GPOS adjustments
gpa = font.performPositioning(mcs, script, language);
} else if (font.hasKerning()) {
// handle standard (non-GPOS) kerning adjustments
gpa = getKerningAdjustments(mcs, font);
} else {
gpa = null;
}

// 5. reorder combining marks so that they precede (within the mapped char sequence) the
// base to which they are applied; N.B. position adjustments (gpa) are reordered in place
mcs = font.reorderCombiningMarks(mcs, gpa, script, language);

// 6. compute word ipd based on final position adjustments
MinOptMax ipd = MinOptMax.ZERO;
for (int i = 0, n = mcs.length(); i < n; i++) {
int c = mcs.charAt(i);
// TODO !BMP
int w = font.getCharWidth(c);
if (w < 0) {
w = 0;
}
if (gpa != null) {
w += gpa[i][GlyphPositioningTable.Value.IDX_X_ADVANCE];
}
ipd = ipd.plus(w);
}

// [TBD] - handle letter spacing

return new GlyphMapping(startIndex, e, 0, nLS, ipd, endsWithHyphen, false,
breakOpportunityChar != 0, font, level, gpa,
CharUtilities.isSameSequence(mcs, ics) ? null : mcs.toString());
}

/**
* Given a mapped character sequence MCS, obtain glyph position adjustments from the
* font's kerning data.
*
* @param mcs mapped character sequence
* @param font applicable font
* @return glyph position adjustments (or null if no kerning)
*/
private static int[][] getKerningAdjustments(CharSequence mcs, final Font font) {
int nc = mcs.length();
// extract kerning array
int[] ka = new int[nc]; // kerning array
for (int i = 0, n = nc, cPrev = -1; i < n; i++) {
int c = mcs.charAt(i);
// TODO !BMP
if (cPrev >= 0) {
ka[i] = font.getKernValue(cPrev, c);
}
cPrev = c;
}
// was there a non-zero kerning?
boolean hasKerning = false;
for (int i = 0, n = nc; i < n; i++) {
if (ka[i] != 0) {
hasKerning = true;
break;
}
}
// if non-zero kerning, then create and return glyph position adjustment array
if (hasKerning) {
int[][] gpa = new int[nc][4];
for (int i = 0, n = nc; i < n; i++) {
if (i > 0) {
gpa [i - 1][GlyphPositioningTable.Value.IDX_X_ADVANCE] = ka[i];
}
}
return gpa;
} else {
return null;
}
}

private static GlyphMapping processWordNoMapping(TextFragment text, int startIndex, int endIndex,
final Font font, MinOptMax letterSpaceIPD, MinOptMax[] letterSpaceAdjustArray,
char precedingChar, final char breakOpportunityChar, final boolean endsWithHyphen, int level) {
boolean kerning = font.hasKerning();
MinOptMax wordIPD = MinOptMax.ZERO;

if (LOG.isDebugEnabled()) {
LOG.debug("PW: [" + startIndex + "," + endIndex + "]: {"
+ " -M"
+ ", level = " + level
+ " }");
}

for (int i = startIndex; i < endIndex; i++) {
char currentChar = text.charAt(i);

// character width
int charWidth = font.getCharWidth(currentChar);
wordIPD = wordIPD.plus(charWidth);

// kerning
if (kerning) {
int kern = 0;
if (i > startIndex) {
char previousChar = text.charAt(i - 1);
kern = font.getKernValue(previousChar, currentChar);
} else if (precedingChar != 0) {
kern = font.getKernValue(precedingChar, currentChar);
}
if (kern != 0) {
addToLetterAdjust(letterSpaceAdjustArray, i, kern);
wordIPD = wordIPD.plus(kern);
}
}
}
if (kerning
&& (breakOpportunityChar != 0)
&& !isSpace(breakOpportunityChar)
&& endIndex > 0
&& endsWithHyphen) {
int kern = font.getKernValue(text.charAt(endIndex - 1), breakOpportunityChar);
if (kern != 0) {
addToLetterAdjust(letterSpaceAdjustArray, endIndex, kern);
// TODO: add kern to wordIPD?
}
}
// shy+chars at start of word: wordLength == 0 && breakOpportunity
// shy only characters in word: wordLength == 0 && !breakOpportunity
int wordLength = endIndex - startIndex;
int letterSpaces = 0;
if (wordLength != 0) {
letterSpaces = wordLength - 1;
// if there is a break opportunity and the next one (break character)
// is not a space, it could be used as a line end;
// add one more letter space, in case other text follows
if ((breakOpportunityChar != 0) && !isSpace(breakOpportunityChar)) {
letterSpaces++;
}
}
assert letterSpaces >= 0;
wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces));

// create and return the AreaInfo object
return new GlyphMapping(startIndex, endIndex, 0,
letterSpaces, wordIPD,
endsWithHyphen,
false, breakOpportunityChar != 0, font, level, null);
}

private static void addToLetterAdjust(MinOptMax[] letterSpaceAdjustArray, int index, int width) {
if (letterSpaceAdjustArray[index] == null) {
letterSpaceAdjustArray[index] = MinOptMax.getInstance(width);
} else {
letterSpaceAdjustArray[index] = letterSpaceAdjustArray[index].plus(width);
}
}

/**
* Indicates whether a character is a space in terms of this layout manager.
*
* @param ch the character
* @return true if it's a space
*/
public static boolean isSpace(final char ch) {
return ch == CharUtilities.SPACE
|| CharUtilities.isNonBreakableSpace(ch)
|| CharUtilities.isFixedWidthSpace(ch);
}

/**
* Obtain number of 'characters' contained in word. If word is mapped, then this
* number may be less than or greater than the original length (breakIndex -
* startIndex). We compute and memoize thius length upon first invocation of this
* method.
*/
public int getWordLength() {
if (wordCharLength == -1) {
if (mapping != null) {
wordCharLength = mapping.length();
} else {
assert endIndex >= startIndex;
wordCharLength = endIndex - startIndex;
}
}
return wordCharLength;
}

public void addToAreaIPD(MinOptMax idp) {
areaIPD = areaIPD.plus(idp);
}

public String toString() {
return super.toString() + "{"
+ "interval = [" + startIndex + "," + endIndex + "]"
+ ", isSpace = " + isSpace
+ ", level = " + level
+ ", areaIPD = " + areaIPD
+ ", letterSpaceCount = " + letterSpaceCount
+ ", wordSpaceCount = " + wordSpaceCount
+ ", isHyphenated = " + isHyphenated
+ ", font = " + font
+ "}";
}

}

+ 26
- 0
src/java/org/apache/fop/fonts/LazyFont.java View File

@@ -18,6 +18,7 @@
/* $Id$ */

package org.apache.fop.fonts;
import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
@@ -250,6 +251,26 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable,
return realFont.getXHeight(size);
}

public int getUnderlinePosition(int size) {
load(true);
return realFont.getUnderlinePosition(size);
}

public int getUnderlineThickness(int size) {
load(true);
return realFont.getUnderlineThickness(size);
}

public int getStrikeoutPosition(int size) {
load(true);
return realFont.getStrikeoutPosition(size);
}

public int getStrikeoutThickness(int size) {
load(true);
return realFont.getStrikeoutThickness(size);
}

/**
* {@inheritDoc}
*/
@@ -268,6 +289,11 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable,
return realFont.getWidths();
}

public Rectangle getBoundingBox(int glyphIndex, int size) {
load(true);
return realFont.getBoundingBox(glyphIndex, size);
}

/**
* {@inheritDoc}
*/

+ 18
- 0
src/java/org/apache/fop/fonts/MultiByteFont.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.fonts;

import java.awt.Rectangle;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.util.BitSet;
@@ -67,6 +68,9 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
private int firstUnmapped;
private int lastUnmapped;

/** Contains the character bounding boxes for all characters in the font */
protected Rectangle[] boundingBoxes;

/**
* Default constructor
*/
@@ -170,6 +174,12 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
return arr;
}

public Rectangle getBoundingBox(int glyphIndex, int size) {
int index = isEmbeddable() ? cidSet.getOriginalGlyphIndex(glyphIndex) : glyphIndex;
Rectangle bbox = boundingBoxes[index];
return new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size);
}

/**
* Returns the glyph index for a Unicode character. The method returns 0 if there's no
* such glyph in the character map.
@@ -365,6 +375,14 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
this.width = wds;
}

/**
* Sets the bounding boxes array.
* @param boundingBoxes array of bounding boxes.
*/
public void setBBoxArray(Rectangle[] boundingBoxes) {
this.boundingBoxes = boundingBoxes;
}

/**
* Returns a Map of used Glyphs.
* @return Map Map of used Glyphs

+ 37
- 3
src/java/org/apache/fop/fonts/SingleByteFont.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.fonts;

import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -47,6 +48,8 @@ public class SingleByteFont extends CustomFont {

private int[] width = null;

private Rectangle[] boundingBoxes;

private Map<Character, UnencodedCharacter> unencodedCharacters;
private List<SimpleSingleByteEncoding> additionalEncodings;
private Map<Character, Character> alternativeCodes;
@@ -111,6 +114,24 @@ public class SingleByteFont extends CustomFont {
return arr;
}

public Rectangle getBoundingBox(int glyphIndex, int size) {
Rectangle bbox = null;
if (glyphIndex < 256) {
int idx = glyphIndex - getFirstChar();
if (idx >= 0 && idx < boundingBoxes.length) {
bbox = boundingBoxes[idx];
}
} else if (this.additionalEncodings != null) {
int encodingIndex = (glyphIndex / 256) - 1;
SimpleSingleByteEncoding encoding = getAdditionalEncoding(encodingIndex);
int codePoint = glyphIndex % 256;
NamedCharacter nc = encoding.getCharacterForIndex(codePoint);
UnencodedCharacter uc = this.unencodedCharacters.get(Character.valueOf(nc.getSingleUnicodeValue()));
bbox = uc.getBBox();
}
return bbox == null ? null : new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size);
}

/**
* Lookup a character using its alternative names. If found, cache it so we
* can speed up lookups.
@@ -292,17 +313,24 @@ public class SingleByteFont extends CustomFont {
this.width[index - getFirstChar()] = w;
}

public void setBoundingBox(int index, Rectangle bbox) {
if (this.boundingBoxes == null) {
this.boundingBoxes = new Rectangle[getLastChar() - getFirstChar() + 1];
}
this.boundingBoxes[index - getFirstChar()] = bbox;
}

/**
* Adds an unencoded character (one that is not supported by the primary encoding).
* @param ch the named character
* @param width the width of the character
*/
public void addUnencodedCharacter(NamedCharacter ch, int width) {
public void addUnencodedCharacter(NamedCharacter ch, int width, Rectangle bbox) {
if (this.unencodedCharacters == null) {
this.unencodedCharacters = new HashMap<Character, UnencodedCharacter>();
}
if (ch.hasSingleUnicodeValue()) {
UnencodedCharacter uc = new UnencodedCharacter(ch, width);
UnencodedCharacter uc = new UnencodedCharacter(ch, width, bbox);
this.unencodedCharacters.put(Character.valueOf(ch.getSingleUnicodeValue()), uc);
} else {
//Cannot deal with unicode sequences, so ignore this character
@@ -381,10 +409,12 @@ public class SingleByteFont extends CustomFont {

private final NamedCharacter character;
private final int width;
private final Rectangle bbox;

public UnencodedCharacter(NamedCharacter character, int width) {
public UnencodedCharacter(NamedCharacter character, int width, Rectangle bbox) {
this.character = character;
this.width = width;
this.bbox = bbox;
}

public NamedCharacter getCharacter() {
@@ -395,6 +425,10 @@ public class SingleByteFont extends CustomFont {
return this.width;
}

public Rectangle getBBox() {
return bbox;
}

/** {@inheritDoc} */
@Override
public String toString() {

+ 31
- 0
src/java/org/apache/fop/fonts/TextFragment.java View File

@@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.fonts;

public interface TextFragment {

String getScript();

String getLanguage();

char charAt(int index);

CharSequence subSequence(int startIndex, int endIndex);
}

+ 36
- 2
src/java/org/apache/fop/fonts/truetype/TTFFile.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.fonts.truetype;

import java.awt.Rectangle;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -199,6 +200,8 @@ public class TTFFile {
private int os2CapHeight = 0;
private int underlinePosition = 0;
private int underlineThickness = 0;
private int strikeoutPosition;
private int strikeoutThickness;
private int xHeight = 0;
private int os2xHeight = 0;
//Effective ascender/descender
@@ -976,10 +979,22 @@ public class TTFFile {
for (int i = 0; i < wx.length; i++) {
wx[i] = convertTTFUnit2PDFUnit(mtxTab[i].getWx());
}

return wx;
}

public Rectangle[] getBoundingBoxes() {
Rectangle[] boundingBoxes = new Rectangle[mtxTab.length];
for (int i = 0; i < boundingBoxes.length; i++) {
int[] boundingBox = mtxTab[i].getBoundingBox();
boundingBoxes[i] = new Rectangle(
convertTTFUnit2PDFUnit(boundingBox[0]),
convertTTFUnit2PDFUnit(boundingBox[1]),
convertTTFUnit2PDFUnit(boundingBox[2] - boundingBox[0]),
convertTTFUnit2PDFUnit(boundingBox[3] - boundingBox[1]));
}
return boundingBoxes;
}

/**
* Returns an array (xMin, yMin, xMax, yMax) for a glyph.
*
@@ -1020,6 +1035,22 @@ public class TTFFile {
return ansiKerningTab;
}

public int getUnderlinePosition() {
return convertTTFUnit2PDFUnit(underlinePosition);
}

public int getUnderlineThickness() {
return convertTTFUnit2PDFUnit(underlineThickness);
}

public int getStrikeoutPosition() {
return convertTTFUnit2PDFUnit(strikeoutPosition);
}

public int getStrikeoutThickness() {
return convertTTFUnit2PDFUnit(strikeoutThickness);
}

/**
* Indicates if the font may be embedded.
* @return boolean True if it may be embedded
@@ -1301,7 +1332,10 @@ public class TTFFile {
} else {
isEmbeddable = true;
}
fontFile.skip(11 * 2);
fontFile.skip(8 * 2);
strikeoutThickness = fontFile.readTTFShort();
strikeoutPosition = fontFile.readTTFShort();
fontFile.skip(2);
fontFile.skip(10); //panose array
fontFile.skip(4 * 4); //unicode ranges
fontFile.skip(4);

+ 14
- 6
src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.fonts.truetype;

import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
@@ -144,6 +145,10 @@ public class TTFFontLoader extends FontLoader {
returnFont.setAscender(ttf.getLowerCaseAscent());
returnFont.setDescender(ttf.getLowerCaseDescent());
returnFont.setFontBBox(ttf.getFontBBox());
returnFont.setUnderlinePosition(ttf.getUnderlinePosition() - ttf.getUnderlineThickness() / 2);
returnFont.setUnderlineThickness(ttf.getUnderlineThickness());
returnFont.setStrikeoutPosition(ttf.getStrikeoutPosition() - ttf.getStrikeoutThickness() / 2);
returnFont.setStrikeoutThickness(ttf.getStrikeoutThickness());
returnFont.setFlags(ttf.getFlags());
returnFont.setStemV(Integer.parseInt(ttf.getStemV())); //not used for TTF
returnFont.setItalicAngle(Integer.parseInt(ttf.getItalicAngle()));
@@ -152,15 +157,15 @@ public class TTFFontLoader extends FontLoader {
returnFont.setEmbeddingMode(this.embeddingMode);
if (isCid) {
multiFont.setCIDType(CIDFontType.CIDTYPE2);
int[] wx = ttf.getWidths();
multiFont.setWidthArray(wx);
multiFont.setWidthArray(ttf.getWidths());
multiFont.setBBoxArray(ttf.getBoundingBoxes());
} else {
singleFont.setFontType(FontType.TRUETYPE);
singleFont.setEncoding(ttf.getCharSetName());
returnFont.setFirstChar(ttf.getFirstChar());
returnFont.setLastChar(ttf.getLastChar());
singleFont.setTrueTypePostScriptVersion(ttf.getPostScriptVersion());
copyWidthsSingleByte(ttf);
copyGlyphMetricsSingleByte(ttf);
}
returnFont.setCMap(getCMap(ttf));

@@ -186,12 +191,15 @@ public class TTFFontLoader extends FontLoader {
return ttf.getCMaps().toArray(array);
}

private void copyWidthsSingleByte(TTFFile ttf) {
private void copyGlyphMetricsSingleByte(TTFFile ttf) {
int[] wx = ttf.getWidths();
Rectangle[] bboxes = ttf.getBoundingBoxes();
for (int i = singleFont.getFirstChar(); i <= singleFont.getLastChar(); i++) {
singleFont.setWidth(i, ttf.getCharWidth(i));
int[] bbox = ttf.getBBox(i);
singleFont.setBoundingBox(i,
new Rectangle(bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]));
}

for (CMapSegment segment : ttf.getCMaps()) {
if (segment.getUnicodeStart() < 0xFFFE) {
for (char u = (char)segment.getUnicodeStart(); u <= segment.getUnicodeEnd(); u++) {
@@ -205,7 +213,7 @@ public class TTFFontLoader extends FontLoader {
if (glyphName.length() > 0) {
String unicode = Character.toString(u);
NamedCharacter nc = new NamedCharacter(glyphName, unicode);
singleFont.addUnencodedCharacter(nc, wx[glyphIndex]);
singleFont.addUnencodedCharacter(nc, wx[glyphIndex], bboxes[glyphIndex]);
}
}
}

+ 4
- 4
src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java View File

@@ -19,7 +19,7 @@

package org.apache.fop.fonts.type1;

import java.awt.geom.RectangularShape;
import java.awt.Rectangle;

import org.apache.fop.fonts.NamedCharacter;

@@ -33,7 +33,7 @@ public class AFMCharMetrics {
private NamedCharacter character;
private double widthX;
private double widthY;
private RectangularShape bBox;
private Rectangle bBox;

/**
* Returns the character code.
@@ -137,7 +137,7 @@ public class AFMCharMetrics {
* Returns the character's bounding box.
* @return the bounding box (or null if it isn't available)
*/
public RectangularShape getBBox() {
public Rectangle getBBox() {
return bBox;
}

@@ -145,7 +145,7 @@ public class AFMCharMetrics {
* Sets the character's bounding box.
* @param box the bounding box
*/
public void setBBox(RectangularShape box) {
public void setBBox(Rectangle box) {
bBox = box;
}


+ 12
- 5
src/java/org/apache/fop/fonts/type1/Type1FontLoader.java View File

@@ -203,12 +203,16 @@ public class Type1FontLoader extends FontLoader {
for (AFMCharMetrics metrics : charMetrics) {
String charName = metrics.getCharName();
if (charName != null && !glyphNames.contains(charName)) {
singleFont.addUnencodedCharacter(metrics.getCharacter(),
(int)Math.round(metrics.getWidthX()));
addUnencodedCharacter(singleFont, metrics);
}
}
}

private static void addUnencodedCharacter(SingleByteFont font, AFMCharMetrics metrics) {
font.addUnencodedCharacter(metrics.getCharacter(),
(int) Math.round(metrics.getWidthX()), metrics.getBBox());
}

/**
* Adds characters not encoded in the font's primary encoding. This method is used when
* the primary encoding is built based on the character codes in the AFM rather than
@@ -220,8 +224,7 @@ public class Type1FontLoader extends FontLoader {
for (int i = 0, c = afm.getCharCount(); i < c; i++) {
AFMCharMetrics metrics = (AFMCharMetrics)charMetrics.get(i);
if (!metrics.hasCharCode() && metrics.getCharacter() != null) {
singleFont.addUnencodedCharacter(metrics.getCharacter(),
(int)Math.round(metrics.getWidthX()));
addUnencodedCharacter(singleFont, metrics);
}
}
}
@@ -267,7 +270,10 @@ public class Type1FontLoader extends FontLoader {
} else {
returnFont.setStemV(80); // Arbitrary value
}
returnFont.setItalicAngle((int) afm.getWritingDirectionMetrics(0).getItalicAngle());
AFMWritingDirectionMetrics metrics = afm.getWritingDirectionMetrics(0);
returnFont.setItalicAngle((int) metrics.getItalicAngle());
returnFont.setUnderlinePosition(metrics.getUnderlinePosition().intValue());
returnFont.setUnderlineThickness(metrics.getUnderlineThickness().intValue());
} else {
returnFont.setFontBBox(pfm.getFontBBox());
returnFont.setStemV(pfm.getStemV());
@@ -369,6 +375,7 @@ public class Type1FontLoader extends FontLoader {
for (AFMCharMetrics chm : afm.getCharMetrics()) {
if (chm.hasCharCode()) {
singleFont.setWidth(chm.getCharCode(), (int) Math.round(chm.getWidthX()));
singleFont.setBoundingBox(chm.getCharCode(), chm.getBBox());
}
}
if (useKerning) {

+ 3
- 4
src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java View File

@@ -33,6 +33,7 @@ import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.font.DefaultFontFamilyResolver;

import org.apache.xmlgraphics.image.GraphicsConstants;
import org.apache.xmlgraphics.image.loader.Image;
@@ -123,10 +124,8 @@ public class ImageConverterSVG2G2D extends AbstractImageConverter {
* @return the newly created user agent
*/
protected SimpleSVGUserAgent createBatikUserAgent(float pxToMillimeter) {
return new SimpleSVGUserAgent(
pxToMillimeter,
new AffineTransform()) {

return new SimpleSVGUserAgent(pxToMillimeter, new AffineTransform(),
DefaultFontFamilyResolver.SINGLETON) {
/** {@inheritDoc} */
public void displayMessage(String message) {
//TODO Refine and pipe through to caller

+ 2
- 1
src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java View File

@@ -38,6 +38,7 @@ import org.apache.batik.bridge.UnitProcessor;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.dom.svg.SVGOMDocument;
import org.apache.batik.gvt.font.DefaultFontFamilyResolver;

import org.apache.xmlgraphics.image.loader.ImageContext;
import org.apache.xmlgraphics.image.loader.ImageInfo;
@@ -162,7 +163,7 @@ public class PreloaderSVG extends AbstractImagePreloader {
Element e = doc.getRootElement();
float pxUnitToMillimeter = UnitConv.IN2MM / context.getSourceResolution();
UserAgent userAg = new SimpleSVGUserAgent(pxUnitToMillimeter,
new AffineTransform()) {
new AffineTransform(), DefaultFontFamilyResolver.SINGLETON) {

/** {@inheritDoc} */
public void displayMessage(String message) {

+ 232
- 487
src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
File diff suppressed because it is too large
View File


+ 3
- 1
src/java/org/apache/fop/render/AbstractGenericSVGHandler.java View File

@@ -31,6 +31,7 @@ import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.dom.AbstractDocument;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.font.DefaultFontFamilyResolver;

import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;

@@ -122,7 +123,8 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC

//Prepare
FOUserAgent userAgent = rendererContext.getUserAgent();
SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new AffineTransform());
SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, DefaultFontFamilyResolver.SINGLETON,
new AffineTransform());

//Create Batik BridgeContext
final BridgeContext bridgeContext = new BridgeContext(svgUserAgent);

+ 8
- 7
src/java/org/apache/fop/render/afp/AFPSVGHandler.java View File

@@ -29,6 +29,7 @@ import org.w3c.dom.Document;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.font.DefaultFontFamilyResolver;

import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
@@ -43,6 +44,7 @@ import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceManager;
import org.apache.fop.afp.AFPUnitConverter;
import org.apache.fop.afp.svg.AFPBridgeContext;
import org.apache.fop.afp.svg.AFPFontFamilyResolver;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.image.loader.batik.BatikUtil;
@@ -53,6 +55,7 @@ import org.apache.fop.render.RendererContext;
import org.apache.fop.render.RendererContext.RendererContextWrapper;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
import org.apache.fop.svg.font.AggregatingFontFamilyResolver;

/**
* AFP XML handler for SVG. Uses Apache Batik for SVG processing.
@@ -196,15 +199,13 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
*/
public static BridgeContext createBridgeContext(FOUserAgent userAgent, AFPGraphics2D g2d) {
ImageManager imageManager = userAgent.getImageManager();

SVGUserAgent svgUserAgent
= new SVGUserAgent(userAgent, new AffineTransform());

ImageSessionContext imageSessionContext = userAgent.getImageSessionContext();

FontInfo fontInfo = g2d.getFontInfo();
SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new AggregatingFontFamilyResolver(
new AFPFontFamilyResolver(fontInfo, userAgent.getEventBroadcaster()), DefaultFontFamilyResolver.SINGLETON),
new AffineTransform());
ImageSessionContext imageSessionContext = userAgent.getImageSessionContext();
return new AFPBridgeContext(svgUserAgent, fontInfo, imageManager, imageSessionContext,
new AffineTransform(), g2d);
new AffineTransform(), g2d, userAgent.getEventBroadcaster());
}

/** {@inheritDoc} */

+ 21
- 0
src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java View File

@@ -21,6 +21,7 @@ package org.apache.fop.render.java2d;

import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
@@ -183,11 +184,31 @@ public class CustomFontMetricsMapper extends Typeface implements FontMetricsMapp
return typeface.getWidths();
}

public Rectangle getBoundingBox(int glyphIndex, int size) {
return typeface.getBoundingBox(glyphIndex, size);
}

/** {@inheritDoc} */
public final int getXHeight(final int size) {
return typeface.getXHeight(size);
}

public int getUnderlinePosition(int size) {
return typeface.getUnderlinePosition(size);
}

public int getUnderlineThickness(int size) {
return typeface.getUnderlineThickness(size);
}

public int getStrikeoutPosition(int size) {
return typeface.getStrikeoutPosition(size);
}

public int getStrikeoutThickness(int size) {
return typeface.getStrikeoutThickness(size);
}

/** {@inheritDoc} */
public final boolean hasKerningInfo() {
return typeface.hasKerningInfo();

+ 20
- 0
src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java View File

@@ -223,6 +223,26 @@ public class Java2DFontMetrics {
return xHeight * 1000;
}

public int getUnderlinePosition(String family, int style, int size) {
setFont(family, style, size);
return -Math.round(lineMetrics.getUnderlineOffset());
}

public int getUnderlineThickness(String family, int style, int size) {
setFont(family, style, size);
return Math.round(lineMetrics.getUnderlineThickness());
}

public int getStrikeoutPosition(String family, int style, int size) {
setFont(family, style, size);
return -Math.round(lineMetrics.getStrikethroughOffset());
}

public int getStrikeoutThickness(String family, int style, int size) {
setFont(family, style, size);
return Math.round(lineMetrics.getStrikethroughThickness());
}

/**
* Returns width (in 1/1000ths of point size) of character at
* code point i

+ 3
- 2
src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java View File

@@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.font.DefaultFontFamilyResolver;

import org.apache.fop.image.loader.batik.BatikUtil;
import org.apache.fop.render.AbstractGenericSVGHandler;
@@ -128,8 +129,8 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler

int x = info.currentXPosition;
int y = info.currentYPosition;
SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), DefaultFontFamilyResolver.SINGLETON,
new AffineTransform());

BridgeContext ctx = new BridgeContext(ua);


+ 21
- 0
src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java View File

@@ -20,6 +20,7 @@
package org.apache.fop.render.java2d;

// Java
import java.awt.Rectangle;
import java.util.Map;
import java.util.Set;

@@ -133,6 +134,22 @@ public class SystemFontMetricsMapper extends Typeface implements FontMetricsMapp
return java2DFontMetrics.getXHeight(family, style, size);
}

public int getUnderlinePosition(int size) {
return java2DFontMetrics.getUnderlinePosition(family, style, size);
}

public int getUnderlineThickness(int size) {
return java2DFontMetrics.getUnderlineThickness(family, style, size);
}

public int getStrikeoutPosition(int size) {
return java2DFontMetrics.getStrikeoutPosition(family, style, size);
}

public int getStrikeoutThickness(int size) {
return java2DFontMetrics.getStrikeoutThickness(family, style, size);
}

/**
* {@inheritDoc}
*/
@@ -148,6 +165,10 @@ public class SystemFontMetricsMapper extends Typeface implements FontMetricsMapp
return java2DFontMetrics.getWidths(family, style, Java2DFontMetrics.FONT_SIZE);
}

public Rectangle getBoundingBox(int glyphIndex, int size) {
throw new UnsupportedOperationException("Not implemented");
}

/**
* {@inheritDoc}
*/

+ 3
- 1
src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java View File

@@ -52,6 +52,7 @@ import org.apache.fop.svg.PDFBridgeContext;
import org.apache.fop.svg.PDFGraphics2D;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;

/**
* Image Handler implementation which handles SVG images.
@@ -76,7 +77,8 @@ public class PDFImageHandlerSVG implements ImageHandler {
}

final float uaResolution = userAgent.getSourceResolution();
SVGUserAgent ua = new SVGUserAgent(userAgent, new AffineTransform());
SVGUserAgent ua = new SVGUserAgent(userAgent, new FOPFontFamilyResolverImpl(pdfContext.getFontInfo()),
new AffineTransform());

GVTBuilder builder = new GVTBuilder();


+ 3
- 0
src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java View File

@@ -40,6 +40,7 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.AbstractFOPTranscoder;
import org.apache.fop.svg.PDFDocumentGraphics2DConfigurator;
import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;

/**
* <p>This class enables to transcode an input to a PostScript document.</p>
@@ -115,6 +116,8 @@ public abstract class AbstractPSTranscoder extends AbstractFOPTranscoder {
this.fontInfo = PDFDocumentGraphics2DConfigurator.createFontInfo(
getEffectiveConfiguration(), useComplexScriptFeatures);
graphics.setCustomTextHandler(new NativeTextHandler(graphics, fontInfo));
((FOPTranscoderUserAgent) userAgent).setFontFamilyResolver(
new FOPFontFamilyResolverImpl(fontInfo));
} catch (FOPException fe) {
throw new TranscoderException(fe);
}

+ 3
- 2
src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java View File

@@ -41,6 +41,7 @@ import org.apache.fop.render.ImageHandler;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;

/**
* Image handler implementation which handles SVG images for PostScript output.
@@ -62,8 +63,8 @@ public class PSImageHandlerSVG implements ImageHandler {
boolean strokeText = false;
//TODO Configure text stroking

SVGUserAgent ua
= new SVGUserAgent(context.getUserAgent(), new AffineTransform());
SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(),
new FOPFontFamilyResolverImpl(psContext.getFontInfo()), new AffineTransform());

PSGraphics2D graphics = new PSGraphics2D(strokeText, gen);
graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());

+ 1
- 2
src/java/org/apache/fop/render/ps/PSSVGHandler.java View File

@@ -249,8 +249,7 @@ public class PSSVGHandler extends AbstractGenericSVGHandler
strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText);
}

SVGUserAgent ua
= new SVGUserAgent(context.getUserAgent(), new AffineTransform());
SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), null /* TODO */, new AffineTransform());

PSGraphics2D graphics = new PSGraphics2D(strokeText, gen);
graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());

+ 132
- 229
src/java/org/apache/fop/render/ps/PSTextPainter.java View File

@@ -19,25 +19,21 @@

package org.apache.fop.render.ps;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Point2D.Double;
import java.io.IOException;
import java.text.AttributedCharacterIterator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.batik.gvt.text.TextSpanLayout;

import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
import org.apache.xmlgraphics.ps.PSGenerator;
@@ -48,7 +44,6 @@ import org.apache.fop.fonts.FontMetrics;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.svg.NativeTextPainter;
import org.apache.fop.util.CharUtilities;
import org.apache.fop.util.HexEncoder;

/**
@@ -62,10 +57,20 @@ import org.apache.fop.util.HexEncoder;
*/
public class PSTextPainter extends NativeTextPainter {

private static final boolean DEBUG = false;

private FontResourceCache fontResources;

private PSGraphics2D ps;

private PSGenerator gen;

private TextUtil textUtil;

private boolean flushCurrentRun;

private PSTextRun psRun;

private Double relPos;

private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform();

/**
@@ -82,165 +87,26 @@ public class PSTextPainter extends NativeTextPainter {
return g2d instanceof PSGraphics2D;
}

/** {@inheritDoc} */
protected void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException {
AttributedCharacterIterator runaci = textRun.getACI();
runaci.first();

TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
if (tpi == null || !tpi.visible) {
return;
}
if ((tpi != null) && (tpi.composite != null)) {
g2d.setComposite(tpi.composite);
}

//------------------------------------
TextSpanLayout layout = textRun.getLayout();
logTextRun(runaci, layout);
CharSequence chars = collectCharacters(runaci);
runaci.first(); //Reset ACI

final PSGraphics2D ps = (PSGraphics2D)g2d;
final PSGenerator gen = ps.getPSGenerator();
@Override
protected void preparePainting(Graphics2D g2d) {
ps = (PSGraphics2D) g2d;
gen = ps.getPSGenerator();
ps.preparePainting();
}

if (DEBUG) {
log.debug("Text: " + chars);
gen.commentln("%Text: " + chars);
}

GeneralPath debugShapes = null;
if (DEBUG) {
debugShapes = new GeneralPath();
}

TextUtil textUtil = new TextUtil(gen);
textUtil.setupFonts(runaci);
if (!textUtil.hasFonts()) {
//Draw using Java2D when no native fonts are available
textRun.getLayout().draw(g2d);
return;
}

@Override
protected void saveGraphicsState() throws IOException {
gen.saveGraphicsState();
gen.concatMatrix(g2d.getTransform());
Shape imclip = g2d.getClip();
clip(ps, imclip);

gen.writeln("BT"); //beginTextObject()

AffineTransform localTransform = new AffineTransform();
Point2D prevPos = null;
GVTGlyphVector gv = layout.getGlyphVector();
PSTextRun psRun = new PSTextRun(); //Used to split a text run into smaller runs
for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) {
char ch = chars.charAt(index);
boolean visibleChar = gv.isGlyphVisible(index)
|| (CharUtilities.isAnySpace(ch) && !CharUtilities.isZeroWidthSpace(ch));
logCharacter(ch, layout, index, visibleChar);
if (!visibleChar) {
continue;
}
Point2D glyphPos = gv.getGlyphPosition(index);

AffineTransform glyphTransform = gv.getGlyphTransform(index);
if (log.isTraceEnabled()) {
log.trace("pos " + glyphPos + ", transform " + glyphTransform);
}
if (DEBUG) {
Shape sh = gv.getGlyphLogicalBounds(index);
if (sh == null) {
sh = new Ellipse2D.Double(glyphPos.getX(), glyphPos.getY(), 2, 2);
}
debugShapes.append(sh, false);
}

//Exact position of the glyph
localTransform.setToIdentity();
localTransform.translate(glyphPos.getX(), glyphPos.getY());
if (glyphTransform != null) {
localTransform.concatenate(glyphTransform);
}
localTransform.scale(1, -1);

boolean flushCurrentRun = false;
//Try to optimize by combining characters using the same font and on the same line.
if (glyphTransform != null) {
//Happens for text-on-a-path
flushCurrentRun = true;
}
if (psRun.getRunLength() >= 128) {
//Don't let a run get too long
flushCurrentRun = true;
}

//Note the position of the glyph relative to the previous one
Point2D relPos;
if (prevPos == null) {
relPos = new Point2D.Double(0, 0);
} else {
relPos = new Point2D.Double(
glyphPos.getX() - prevPos.getX(),
glyphPos.getY() - prevPos.getY());
}
if (psRun.vertChanges == 0
&& psRun.getHorizRunLength() > 2
&& relPos.getY() != 0) {
//new line
flushCurrentRun = true;
}

//Select the actual character to paint
char paintChar = (CharUtilities.isAnySpace(ch) ? ' ' : ch);

//Select (sub)font for character
Font f = textUtil.selectFontForChar(paintChar);
char mapped = f.mapChar(ch);
boolean fontChanging = textUtil.isFontChanging(f, mapped);
if (fontChanging) {
flushCurrentRun = true;
}

if (flushCurrentRun) {
//Paint the current run and reset for the next run
psRun.paint(ps, textUtil, tpi);
psRun.reset();
}

//Track current run
psRun.addCharacter(paintChar, relPos);
psRun.noteStartingTransformation(localTransform);

//Change font if necessary
if (fontChanging) {
textUtil.setCurrentFont(f, mapped);
}
}

//Update last position
prevPos = glyphPos;
}
psRun.paint(ps, textUtil, tpi);
gen.writeln("ET"); //endTextObject()
@Override
protected void restoreGraphicsState() throws IOException {
gen.restoreGraphicsState();

if (DEBUG) {
//Paint debug shapes
g2d.setStroke(new BasicStroke(0));
g2d.setColor(Color.LIGHT_GRAY);
g2d.draw(debugShapes);
}
}

private void applyColor(Paint paint, final PSGenerator gen) throws IOException {
if (paint == null) {
return;
} else if (paint instanceof Color) {
Color col = (Color)paint;
gen.useColor(col);
} else {
log.warn("Paint not supported: " + paint.toString());
}
@Override
protected void setInitialTransform(AffineTransform transform) throws IOException {
gen.concatMatrix(transform);
}

private PSFontResource getResourceForFont(Font f, String postfix) {
@@ -248,7 +114,8 @@ public class PSTextPainter extends NativeTextPainter {
return this.fontResources.getFontResourceForFontKey(key);
}

private void clip(PSGraphics2D ps, Shape shape) throws IOException {
@Override
protected void clip(Shape shape) throws IOException {
if (shape == null) {
return;
}
@@ -258,17 +125,76 @@ public class PSTextPainter extends NativeTextPainter {
ps.getPSGenerator().writeln("clip");
}

@Override
protected void beginTextObject() throws IOException {
gen.writeln("BT");
textUtil = new TextUtil();
psRun = new PSTextRun(); //Used to split a text run into smaller runs
}

@Override
protected void endTextObject() throws IOException {
psRun.paint(ps, textUtil, tpi);
gen.writeln("ET");
}

@Override
protected void positionGlyph(Point2D prevPos, Point2D glyphPos, boolean reposition) {
flushCurrentRun = false;
//Try to optimize by combining characters using the same font and on the same line.
if (reposition) {
//Happens for text-on-a-path
flushCurrentRun = true;
}
if (psRun.getRunLength() >= 128) {
//Don't let a run get too long
flushCurrentRun = true;
}

//Note the position of the glyph relative to the previous one
if (prevPos == null) {
relPos = new Point2D.Double(0, 0);
} else {
relPos = new Point2D.Double(
glyphPos.getX() - prevPos.getX(),
glyphPos.getY() - prevPos.getY());
}
if (psRun.vertChanges == 0
&& psRun.getHorizRunLength() > 2
&& relPos.getY() != 0) {
//new line
flushCurrentRun = true;
}
}

@Override
protected void writeGlyph(char glyph, AffineTransform localTransform) throws IOException {
boolean fontChanging = textUtil.isFontChanging(font, glyph);
if (fontChanging) {
flushCurrentRun = true;
}

if (flushCurrentRun) {
//Paint the current run and reset for the next run
psRun.paint(ps, textUtil, tpi);
psRun.reset();
}

//Track current run
psRun.addGlyph(glyph, relPos);
psRun.noteStartingTransformation(localTransform);

//Change font if necessary
if (fontChanging) {
textUtil.setCurrentFont(font, glyph);
}
}

private class TextUtil {

private PSGenerator gen;
private Font[] fonts;
private Font currentFont;
private int currentEncoding = -1;

public TextUtil(PSGenerator gen) {
this.gen = gen;
}

public boolean isMultiByte(Font f) {
FontMetrics metrics = f.getFontMetrics();
boolean multiByte = metrics instanceof MultiByteFont || metrics instanceof LazyFont
@@ -276,15 +202,6 @@ public class PSTextPainter extends NativeTextPainter {
return multiByte;
}

public Font selectFontForChar(char ch) {
for (int i = 0, c = fonts.length; i < c; i++) {
if (fonts[i].hasChar(ch)) {
return fonts[i];
}
}
return fonts[0]; //TODO Maybe fall back to painting with shapes
}

public void writeTextMatrix(AffineTransform transform) throws IOException {
double[] matrix = new double[6];
transform.getMatrix(matrix);
@@ -335,27 +252,19 @@ public class PSTextPainter extends NativeTextPainter {
setCurrentFont(font, encoding);
}

public void setupFonts(AttributedCharacterIterator runaci) {
this.fonts = findFonts(runaci);
}

public boolean hasFonts() {
return (fonts != null) && (fonts.length > 0);
}

}

private class PSTextRun {

private AffineTransform textTransform;
private List relativePositions = new java.util.LinkedList();
private StringBuffer currentChars = new StringBuffer();
private List<Point2D> relativePositions = new LinkedList<Point2D>();
private StringBuffer currentGlyphs = new StringBuffer();
private int horizChanges = 0;
private int vertChanges = 0;

public void reset() {
textTransform = null;
currentChars.setLength(0);
currentGlyphs.setLength(0);
horizChanges = 0;
vertChanges = 0;
relativePositions.clear();
@@ -369,9 +278,9 @@ public class PSTextPainter extends NativeTextPainter {
return 0;
}

public void addCharacter(char paintChar, Point2D relPos) {
public void addGlyph(char glyph, Point2D relPos) {
addRelativePosition(relPos);
currentChars.append(paintChar);
currentGlyphs.append(glyph);
}

private void addRelativePosition(Point2D relPos) {
@@ -393,7 +302,7 @@ public class PSTextPainter extends NativeTextPainter {
}

public int getRunLength() {
return currentChars.length();
return currentGlyphs.length();
}

private boolean isXShow() {
@@ -407,9 +316,6 @@ public class PSTextPainter extends NativeTextPainter {
public void paint(PSGraphics2D g2d, TextUtil textUtil, TextPaintInfo tpi)
throws IOException {
if (getRunLength() > 0) {
if (log.isDebugEnabled()) {
log.debug("Text run: " + currentChars);
}
textUtil.writeTextMatrix(this.textTransform);
if (isXShow()) {
log.debug("Horizontal text: xshow");
@@ -431,25 +337,20 @@ public class PSTextPainter extends NativeTextPainter {

private void paintXYShow(PSGraphics2D g2d, TextUtil textUtil, Paint paint,
boolean x, boolean y) throws IOException {
PSGenerator gen = textUtil.gen;
char firstChar = this.currentChars.charAt(0);
//Font only has to be setup up before the first character
Font f = textUtil.selectFontForChar(firstChar);
char mapped = f.mapChar(firstChar);
textUtil.selectFont(f, mapped);
textUtil.setCurrentFont(f, mapped);
applyColor(paint, gen);

boolean multiByte = textUtil.isMultiByte(f);
char glyph = currentGlyphs.charAt(0);
textUtil.selectFont(font, glyph);
textUtil.setCurrentFont(font, glyph);
applyColor(paint);

boolean multiByte = textUtil.isMultiByte(font);
StringBuffer sb = new StringBuffer();
sb.append(multiByte ? '<' : '(');
for (int i = 0, c = this.currentChars.length(); i < c; i++) {
char ch = this.currentChars.charAt(i);
mapped = f.mapChar(ch);
for (int i = 0, c = this.currentGlyphs.length(); i < c; i++) {
glyph = this.currentGlyphs.charAt(i);
if (multiByte) {
sb.append(HexEncoder.encode(mapped));
sb.append(HexEncoder.encode(glyph));
} else {
char codepoint = (char) (mapped % 256);
char codepoint = (char) (glyph % 256);
PSGenerator.escapeChar(codepoint, sb);
}
}
@@ -457,9 +358,9 @@ public class PSTextPainter extends NativeTextPainter {
if (x || y) {
sb.append("\n[");
int idx = 0;
Iterator iter = this.relativePositions.iterator();
Iterator<Point2D> iter = this.relativePositions.iterator();
while (iter.hasNext()) {
Point2D pt = (Point2D)iter.next();
Point2D pt = iter.next();
if (idx > 0) {
if (x) {
sb.append(format(gen, pt.getX()));
@@ -500,6 +401,17 @@ public class PSTextPainter extends NativeTextPainter {
gen.writeln(sb.toString());
}

private void applyColor(Paint paint) throws IOException {
if (paint == null) {
return;
} else if (paint instanceof Color) {
Color col = (Color) paint;
gen.useColor(col);
} else {
log.warn("Paint not supported: " + paint.toString());
}
}

private String format(PSGenerator gen, double coord) {
if (Math.abs(coord) < 0.00001) {
return "0";
@@ -510,30 +422,21 @@ public class PSTextPainter extends NativeTextPainter {

private void paintStrokedGlyphs(PSGraphics2D g2d, TextUtil textUtil,
Paint strokePaint, Stroke stroke) throws IOException {
PSGenerator gen = textUtil.gen;

applyColor(strokePaint, gen);
applyColor(strokePaint);
PSGraphics2D.applyStroke(stroke, gen);

Font f = null;
Iterator iter = this.relativePositions.iterator();
Iterator<Point2D> iter = this.relativePositions.iterator();
iter.next();
Point2D pos = new Point2D.Double(0, 0);
gen.writeln("0 0 M");
for (int i = 0, c = this.currentChars.length(); i < c; i++) {
char ch = this.currentChars.charAt(0);
for (int i = 0, c = this.currentGlyphs.length(); i < c; i++) {
char mapped = this.currentGlyphs.charAt(i);
if (i == 0) {
//Font only has to be setup up before the first character
f = textUtil.selectFontForChar(ch);
}
char mapped = f.mapChar(ch);
if (i == 0) {
textUtil.selectFont(f, mapped);
textUtil.setCurrentFont(f, mapped);
textUtil.selectFont(font, mapped);
textUtil.setCurrentFont(font, mapped);
}
//add glyph outlines to current path
mapped = f.mapChar(this.currentChars.charAt(i));
FontMetrics metrics = f.getFontMetrics();
FontMetrics metrics = font.getFontMetrics();
boolean multiByte = metrics instanceof MultiByteFont
|| metrics instanceof LazyFont
&& ((LazyFont) metrics).getRealFont() instanceof MultiByteFont;
@@ -542,14 +445,14 @@ public class PSTextPainter extends NativeTextPainter {
gen.write(HexEncoder.encode(mapped));
gen.write(">");
} else {
char codepoint = (char)(mapped % 256);
char codepoint = (char) (mapped % 256);
gen.write("(" + codepoint + ")");
}
gen.writeln(" false charpath");

if (iter.hasNext()) {
//Position for the next character
Point2D pt = (Point2D)iter.next();
Point2D pt = iter.next();
pos.setLocation(pos.getX() + pt.getX(), pos.getY() - pt.getY());
gen.writeln(gen.formatDouble5(pos.getX()) + " "
+ gen.formatDouble5(pos.getY()) + " M");

+ 20
- 48
src/java/org/apache/fop/svg/ACIUtils.java View File

@@ -38,7 +38,8 @@ import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.svg.font.FOPGVTFont;
import org.apache.fop.svg.font.FOPGVTFontFamily;

/**
* Utilities for java.text.AttributedCharacterIterator.
@@ -64,57 +65,43 @@ public final class ACIUtils {
@SuppressWarnings("unchecked")
List<GVTFontFamily> gvtFonts = (List<GVTFontFamily>) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
Float posture = (Float) aci.getAttribute(TextAttribute.POSTURE);
Float taWeight = (Float) aci.getAttribute(TextAttribute.WEIGHT);
Float fontSize = (Float) aci.getAttribute(TextAttribute.SIZE);

String style = toStyle(posture);
int weight = toCSSWeight(taWeight);
int fsize = (int)(fontSize.floatValue() * 1000);
String style = toStyle((Float) aci.getAttribute(TextAttribute.POSTURE));
int weight = toCSSWeight((Float) aci.getAttribute(TextAttribute.WEIGHT));
float fontSize = ((Float) aci.getAttribute(TextAttribute.SIZE)).floatValue();

String firstFontFamily = null;

//GVT_FONT can sometimes be different from the fonts in GVT_FONT_FAMILIES
//or GVT_FONT_FAMILIES can even be empty and only GVT_FONT is set
/* The following code section is not available until Batik 1.7 is released. */
GVTFont gvtFont = (GVTFont)aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.GVT_FONT);
GVTFont gvtFont = (GVTFont) aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT);
if (gvtFont != null) {
String gvtFontFamily = gvtFont.getFamilyName();
if (fontInfo.hasFont(gvtFontFamily, style, weight)) {
FontTriplet triplet = fontInfo.fontLookup(gvtFontFamily, style,
weight);
Font f = fontInfo.getFontInstance(triplet, fsize);
if (gvtFont instanceof FOPGVTFont) {
Font font = ((FOPGVTFont) gvtFont).getFont();
if (LOG.isDebugEnabled()) {
LOG.debug("Found a font that matches the GVT font: "
+ gvtFontFamily + ", " + weight + ", " + style
+ " -> " + f);
+ " -> " + font);
}
fonts.add(f);
fonts.add(font);
}
firstFontFamily = gvtFontFamily;
}

if (gvtFonts != null) {
boolean haveInstanceOfSVGFontFamily = false;
for (GVTFontFamily fam : gvtFonts) {
if (fam instanceof SVGFontFamily) {
for (GVTFontFamily fontFamily : gvtFonts) {
if (fontFamily instanceof SVGFontFamily) {
haveInstanceOfSVGFontFamily = true;
}
String fontFamily = fam.getFamilyName();
if (fontInfo.hasFont(fontFamily, style, weight)) {
FontTriplet triplet = fontInfo.fontLookup(fontFamily, style,
weight);
Font f = fontInfo.getFontInstance(triplet, fsize);
} else if (fontFamily instanceof FOPGVTFontFamily) {
Font font = ((FOPGVTFontFamily) fontFamily).deriveFont(fontSize, aci).getFont();
if (LOG.isDebugEnabled()) {
LOG.debug("Found a font that matches the GVT font family: "
+ fontFamily + ", " + weight + ", " + style
+ " -> " + f);
+ fontFamily.getFamilyName() + ", " + weight + ", " + style + " -> " + font);
}
fonts.add(f);
fonts.add(font);
}
if (firstFontFamily == null) {
firstFontFamily = fontFamily;
firstFontFamily = fontFamily.getFamilyName();
}
}
// SVG fonts are embedded fonts in the SVG document and are rarely used; however if they
@@ -126,25 +113,10 @@ public final class ACIUtils {
return null; // Let Batik paint this text!
}
}
if (fonts.isEmpty()) {
if (firstFontFamily == null) {
//This will probably never happen. Just to be on the safe side.
firstFontFamily = "any";
}
//lookup with fallback possibility (incl. substitution notification)
FontTriplet triplet = fontInfo.fontLookup(firstFontFamily, style, weight);
Font f = fontInfo.getFontInstance(triplet, fsize);
if (LOG.isDebugEnabled()) {
LOG.debug("Falling back to adjustable font lookup up for: "
+ firstFontFamily + ", " + weight + ", " + style
+ " -> " + f);
}
fonts.add(f);
}
return fonts.toArray(new Font[fonts.size()]);
return fonts.isEmpty() ? null : fonts.toArray(new Font[fonts.size()]);
}

private static int toCSSWeight(Float weight) {
public static int toCSSWeight(Float weight) {
if (weight == null) {
return 400;
} else if (weight <= TextAttribute.WEIGHT_EXTRA_LIGHT.floatValue()) {
@@ -170,7 +142,7 @@ public final class ACIUtils {
}
}

private static String toStyle(Float posture) {
public static String toStyle(Float posture) {
return ((posture != null) && (posture.floatValue() > 0.0))
? Font.STYLE_ITALIC
: Font.STYLE_NORMAL;

+ 92
- 239
src/java/org/apache/fop/svg/AbstractFOPTextPainter.java View File

@@ -23,20 +23,15 @@ import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.font.TextAttribute;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.text.AttributedCharacterIterator;
import java.text.CharacterIterator;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.batik.dom.svg.SVGOMTextElement;
import org.apache.batik.gvt.TextNode;
import org.apache.batik.gvt.TextPainter;
import org.apache.batik.gvt.renderer.StrokingTextPainter;
@@ -66,15 +61,15 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
* Use the stroking text painter to get the bounds and shape.
* Also used as a fallback to draw the string with strokes.
*/
protected static final TextPainter
PROXY_PAINTER = StrokingTextPainter.getInstance();
private final TextPainter proxyTextPainter;

/**
* Create a new PS text painter with the given font information.
* @param nativeTextHandler the NativeTextHandler instance used for text painting
*/
public AbstractFOPTextPainter(FOPTextHandler nativeTextHandler) {
public AbstractFOPTextPainter(FOPTextHandler nativeTextHandler, TextPainter proxyTextPainter) {
this.nativeTextHandler = nativeTextHandler;
this.proxyTextPainter = proxyTextPainter;
}

/**
@@ -85,19 +80,10 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
* @param g2d the Graphics2D to use
*/
public void paint(TextNode node, Graphics2D g2d) {
Point2D loc = node.getLocation();
if (!isSupportedGraphics2D(g2d) || hasUnsupportedAttributes(node)) {
if (log.isDebugEnabled()) {
log.debug("painting text node " + node
+ " by stroking due to unsupported attributes or an incompatible Graphics2D");
}
PROXY_PAINTER.paint(node, g2d);
} else {
if (log.isDebugEnabled()) {
log.debug("painting text node " + node + " normally.");
}
paintTextRuns(node.getTextRuns(), g2d, loc);
if (isSupportedGraphics2D(g2d)) {
new TextRunPainter().paintTextRuns(node.getTextRuns(), g2d, node.getLocation());
}
proxyTextPainter.paint(node, g2d);
}

/**
@@ -109,190 +95,99 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
*/
protected abstract boolean isSupportedGraphics2D(Graphics2D g2d);

private boolean hasUnsupportedAttributes(TextNode node) {
Iterator iter = node.getTextRuns().iterator();
while (iter.hasNext()) {
StrokingTextPainter.TextRun
run = (StrokingTextPainter.TextRun)iter.next();
AttributedCharacterIterator aci = run.getACI();
boolean hasUnsupported = hasUnsupportedAttributes(aci);
if (hasUnsupported) {
return true;
}
}
return false;
}

private boolean hasUnsupportedAttributes(AttributedCharacterIterator aci) {
boolean hasUnsupported = false;

Font font = getFont(aci);
String text = getText(aci);
if (hasUnsupportedGlyphs(text, font)) {
log.trace("-> Unsupported glyphs found");
hasUnsupported = true;
}
private class TextRunPainter {

TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
if ((tpi != null)
&& ((tpi.strokeStroke != null && tpi.strokePaint != null)
|| (tpi.strikethroughStroke != null)
|| (tpi.underlineStroke != null)
|| (tpi.overlineStroke != null))) {
log.trace("-> under/overlines etc. found");
hasUnsupported = true;
}
private Point2D currentLocation;

//Alpha is not supported
Paint foreground = (Paint) aci.getAttribute(TextAttribute.FOREGROUND);
if (foreground instanceof Color) {
Color col = (Color)foreground;
if (col.getAlpha() != 255) {
log.trace("-> transparency found");
hasUnsupported = true;
public void paintTextRuns(Iterable<StrokingTextPainter.TextRun> textRuns, Graphics2D g2d,
Point2D nodeLocation) {
currentLocation = new Point2D.Double(nodeLocation.getX(), nodeLocation.getY());
for (StrokingTextPainter.TextRun run : textRuns) {
paintTextRun(run, g2d);
}
}

Object letSpace = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.LETTER_SPACING);
if (letSpace != null) {
log.trace("-> letter spacing found");
hasUnsupported = true;
}

Object wordSpace = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING);
if (wordSpace != null) {
log.trace("-> word spacing found");
hasUnsupported = true;
}

Object lengthAdjust = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.LENGTH_ADJUST);
if (lengthAdjust != null) {
log.trace("-> length adjustments found");
hasUnsupported = true;
}

Object writeMod = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE);
if (writeMod != null
&& !GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals(
writeMod)) {
log.trace("-> Unsupported writing modes found");
hasUnsupported = true;
}

Object vertOr = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION);
if (GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_ANGLE.equals(
vertOr)) {
log.trace("-> vertical orientation found");
hasUnsupported = true;
}

Object rcDel = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER);
//Batik 1.6 returns null here which makes it impossible to determine whether this can
//be painted or not, i.e. fall back to stroking. :-(
if (rcDel != null && !(rcDel instanceof SVGOMTextElement)) {
log.trace("-> spans found");
hasUnsupported = true; //Filter spans
}

if (hasUnsupported) {
log.trace("Unsupported attributes found in ACI, using StrokingTextPainter");
}
return hasUnsupported;
}

/**
* Paint a list of text runs on the Graphics2D at a given location.
* @param textRuns the list of text runs
* @param g2d the Graphics2D to paint to
* @param loc the current location of the "cursor"
*/
protected void paintTextRuns(List textRuns, Graphics2D g2d, Point2D loc) {
Point2D currentloc = loc;
Iterator i = textRuns.iterator();
while (i.hasNext()) {
StrokingTextPainter.TextRun
run = (StrokingTextPainter.TextRun)i.next();
currentloc = paintTextRun(run, g2d, currentloc);
}
}

/**
* Paint a single text run on the Graphics2D at a given location.
* @param run the text run to paint
* @param g2d the Graphics2D to paint to
* @param loc the current location of the "cursor"
* @return the new location of the "cursor" after painting the text run
*/
protected Point2D paintTextRun(StrokingTextPainter.TextRun run, Graphics2D g2d, Point2D loc) {
AttributedCharacterIterator aci = run.getACI();
aci.first();

updateLocationFromACI(aci, loc);
AffineTransform at = g2d.getTransform();
loc = at.transform(loc, null);

// font
Font font = getFont(aci);
if (font != null) {
nativeTextHandler.setOverrideFont(font);
}

// color
TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
if (tpi == null) {
return loc;
}
Paint foreground = tpi.fillPaint;
if (foreground instanceof Color) {
Color col = (Color)foreground;
g2d.setColor(col);
}
g2d.setPaint(foreground);

// text anchor
TextNode.Anchor anchor = (TextNode.Anchor)aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);

// text
String txt = getText(aci);
float advance = getStringWidth(txt, font);
float tx = 0;
if (anchor != null) {
switch (anchor.getType()) {
case TextNode.Anchor.ANCHOR_MIDDLE:
tx = -advance / 2;
break;
case TextNode.Anchor.ANCHOR_END:
tx = -advance;
break;
default: //nop
private void paintTextRun(StrokingTextPainter.TextRun run, Graphics2D g2d) {
AttributedCharacterIterator aci = run.getACI();
aci.first();
updateLocationFromACI(aci, currentLocation);
// font
Font font = getFont(aci);
if (font != null) {
nativeTextHandler.setOverrideFont(font);
}
}

// draw string
double x = loc.getX();
double y = loc.getY();
try {
// color
TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
if (tpi == null) {
return;
}
Paint foreground = tpi.fillPaint;
if (foreground instanceof Color) {
Color col = (Color) foreground;
g2d.setColor(col);
}
g2d.setPaint(foreground);
// text anchor
TextNode.Anchor anchor = (TextNode.Anchor) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
// text
String txt = getText(aci);
double advance = font == null ? run.getLayout().getAdvance2D().getX() : getStringWidth(txt, font);
double tx = 0;
if (anchor != null) {
switch (anchor.getType()) {
case TextNode.Anchor.ANCHOR_MIDDLE:
tx = -advance / 2;
break;
case TextNode.Anchor.ANCHOR_END:
tx = -advance;
break;
default: //nop
}
}
// draw string
Point2D outputLocation = g2d.getTransform().transform(currentLocation, null);
double x = outputLocation.getX();
double y = outputLocation.getY();
try {
nativeTextHandler.drawString(g2d, txt, (float)x + tx, (float)y);
} catch (IOException ioe) {
if (g2d instanceof AFPGraphics2D) {
((AFPGraphics2D)g2d).handleIOException(ioe);
try {
//TODO draw underline and overline if set
nativeTextHandler.drawString(g2d, txt, (float) (x + tx), (float) y);
//TODO draw strikethrough if set
} catch (IOException ioe) {
if (g2d instanceof AFPGraphics2D) {
((AFPGraphics2D) g2d).handleIOException(ioe);
}
}
} finally {
nativeTextHandler.setOverrideFont(null);
}
currentLocation.setLocation(currentLocation.getX() + advance, currentLocation.getY());
}
private void updateLocationFromACI(AttributedCharacterIterator aci, Point2D loc) {
//Adjust position of span
Float xpos = (Float) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.X);
Float ypos = (Float) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.Y);
Float dxpos = (Float) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.DX);
Float dypos = (Float) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.DY);
if (xpos != null) {
loc.setLocation(xpos.doubleValue(), loc.getY());
}
if (ypos != null) {
loc.setLocation(loc.getX(), ypos.doubleValue());
}
if (dxpos != null) {
loc.setLocation(loc.getX() + dxpos.doubleValue(), loc.getY());
}
if (dypos != null) {
loc.setLocation(loc.getX(), loc.getY() + dypos.doubleValue());
}
} finally {
nativeTextHandler.setOverrideFont(null);
}
loc.setLocation(loc.getX() + advance, loc.getY());
return loc;
}

/**
@@ -305,36 +200,9 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
for (char c = aci.first(); c != CharacterIterator.DONE; c = aci.next()) {
sb.append(c);
}
aci.first();
return sb.toString();
}

private void updateLocationFromACI(
AttributedCharacterIterator aci,
Point2D loc) {
//Adjust position of span
Float xpos = (Float)aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.X);
Float ypos = (Float)aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.Y);
Float dxpos = (Float)aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.DX);
Float dypos = (Float)aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.DY);
if (xpos != null) {
loc.setLocation(xpos.doubleValue(), loc.getY());
}
if (ypos != null) {
loc.setLocation(loc.getX(), ypos.doubleValue());
}
if (dxpos != null) {
loc.setLocation(loc.getX() + dxpos.doubleValue(), loc.getY());
}
if (dypos != null) {
loc.setLocation(loc.getX(), loc.getY() + dypos.doubleValue());
}
}

private Font getFont(AttributedCharacterIterator aci) {
Font[] fonts = ACIUtils.findFontsForBatikACI(aci, nativeTextHandler.getFontInfo());
return fonts == null ? null : fonts[0];
@@ -360,21 +228,6 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
return wordWidth / 1000f;
}

private boolean hasUnsupportedGlyphs(String str, Font font) {
if (font == null) {
return true;
}
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) {
if (!font.hasChar(c)) {
return true;
}
}
}
return false;
}

/**
* Get the outline shape of the text characters.
* This uses the StrokingTextPainter to get the outline
@@ -384,7 +237,7 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
* @return the outline shape of the text characters
*/
public Shape getOutline(TextNode node) {
return PROXY_PAINTER.getOutline(node);
return proxyTextPainter.getOutline(node);
}

/**
@@ -399,7 +252,7 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
/* (todo) getBounds2D() is too slow
* because it uses the StrokingTextPainter. We should implement this
* method ourselves. */
return PROXY_PAINTER.getBounds2D(node);
return proxyTextPainter.getBounds2D(node);
}

/**
@@ -411,7 +264,7 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
* @return the bounds of the text
*/
public Rectangle2D getGeometryBounds(TextNode node) {
return PROXY_PAINTER.getGeometryBounds(node);
return proxyTextPainter.getGeometryBounds(node);
}

// Methods that have no purpose for PS

+ 15
- 7
src/java/org/apache/fop/svg/AbstractFOPTranscoder.java View File

@@ -36,9 +36,9 @@ import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.SimpleLog;

import org.apache.batik.bridge.UserAgent;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.dom.util.DocumentFactory;
import org.apache.batik.gvt.font.FontFamilyResolver;
import org.apache.batik.transcoder.ErrorHandler;
import org.apache.batik.transcoder.SVGAbstractTranscoder;
import org.apache.batik.transcoder.TranscoderException;
@@ -56,6 +56,8 @@ import org.apache.xmlgraphics.image.loader.ImageSessionContext;
import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext;
import org.apache.xmlgraphics.util.UnitConv;

import org.apache.fop.svg.font.FOPFontFamilyResolver;

/**
* This is the common base class of all of FOP's transcoders.
*/
@@ -86,11 +88,6 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem
/** The value to turn off text stroking. */
public static final Boolean VALUE_FORMAT_OFF = Boolean.FALSE;

/**
* The user agent dedicated to this Transcoder.
*/
protected UserAgent userAgent = createUserAgent();

private Log logger;
private EntityResolver resolver;
private Configuration cfg = null;
@@ -113,7 +110,7 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem
* this method if you need non-default behaviour.
* @return UserAgent the newly created user agent
*/
protected UserAgent createUserAgent() {
protected FOPTranscoderUserAgent createUserAgent() {
return new FOPTranscoderUserAgent();
}

@@ -331,6 +328,8 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem
*/
protected class FOPTranscoderUserAgent extends SVGAbstractTranscoderUserAgent {

private FOPFontFamilyResolver fontFamilyResolver;

/**
* Displays the specified error message using the {@link ErrorHandler}.
* @param message the message to display
@@ -386,6 +385,15 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem
return "print";
}

public void setFontFamilyResolver(FOPFontFamilyResolver resolver) {
fontFamilyResolver = resolver;
}

@Override
public FontFamilyResolver getFontFamilyResolver() {
return fontFamilyResolver;
}

}

}

+ 132
- 15
src/java/org/apache/fop/svg/NativeTextPainter.java View File

@@ -19,7 +19,14 @@

package org.apache.fop.svg;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.text.AttributedCharacterIterator;
import java.util.List;
@@ -27,11 +34,17 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.batik.bridge.SVGGVTFont;
import org.apache.batik.gvt.font.FontFamilyResolver;
import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.renderer.StrokingTextPainter;
import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.batik.gvt.text.TextSpanLayout;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
import org.apache.fop.svg.font.FOPGVTFont;
import org.apache.fop.util.CharUtilities;

/**
@@ -41,17 +54,26 @@ import org.apache.fop.util.CharUtilities;
public abstract class NativeTextPainter extends StrokingTextPainter {

/** the logger for this class */
protected Log log = LogFactory.getLog(NativeTextPainter.class);
protected static final Log log = LogFactory.getLog(NativeTextPainter.class);

private static final boolean DEBUG = false;

/** the font collection */
protected final FontInfo fontInfo;

protected final FontFamilyResolver fontFamilyResolver;

protected Font font;

protected TextPaintInfo tpi;

/**
* Creates a new instance.
* @param fontInfo the font collection
*/
public NativeTextPainter(FontInfo fontInfo) {
this.fontInfo = fontInfo;
this.fontFamilyResolver = new FOPFontFamilyResolverImpl(fontInfo);
}

/**
@@ -68,11 +90,93 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
* @param g2d the target Graphics2D instance
* @throws IOException if an I/O error occurs while rendering the text
*/
protected abstract void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException;
protected final void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException {
AttributedCharacterIterator runaci = textRun.getACI();
runaci.first();

tpi = (TextPaintInfo) runaci.getAttribute(PAINT_INFO);
if (tpi == null || !tpi.visible) {
return;
}
if (tpi.composite != null) {
g2d.setComposite(tpi.composite);
}

//------------------------------------
TextSpanLayout layout = textRun.getLayout();
logTextRun(runaci, layout);
runaci.first(); //Reset ACI

GeneralPath debugShapes = null;
if (DEBUG) {
debugShapes = new GeneralPath();
}

preparePainting(g2d);

GVTGlyphVector gv = layout.getGlyphVector();
if (!(gv.getFont() instanceof FOPGVTFont)) {
assert gv.getFont() == null || gv.getFont() instanceof SVGGVTFont;
//Draw using Java2D when no native fonts are available
textRun.getLayout().draw(g2d);
return;
}
font = ((FOPGVTFont) gv.getFont()).getFont();

saveGraphicsState();
setInitialTransform(g2d.getTransform());
clip(g2d.getClip());
beginTextObject();

AffineTransform localTransform = new AffineTransform();
Point2D prevPos = null;
AffineTransform prevGlyphTransform = null;
for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) {
if (!gv.isGlyphVisible(index)) {
continue;
}
Point2D glyphPos = gv.getGlyphPosition(index);

AffineTransform glyphTransform = gv.getGlyphTransform(index);
if (log.isTraceEnabled()) {
log.trace("pos " + glyphPos + ", transform " + glyphTransform);
}
if (DEBUG) {
Shape sh = gv.getGlyphLogicalBounds(index);
if (sh == null) {
sh = new Ellipse2D.Double(glyphPos.getX(), glyphPos.getY(), 2, 2);
}
debugShapes.append(sh, false);
}

//Exact position of the glyph
localTransform.setToIdentity();
localTransform.translate(glyphPos.getX(), glyphPos.getY());
if (glyphTransform != null) {
localTransform.concatenate(glyphTransform);
}
localTransform.scale(1, -1);

positionGlyph(prevPos, glyphPos, glyphTransform != null || prevGlyphTransform != null);
char glyph = (char) gv.getGlyphCode(index);
//Update last position
prevPos = glyphPos;
prevGlyphTransform = glyphTransform;

writeGlyph(glyph, localTransform);
}
endTextObject();
restoreGraphicsState();
if (DEBUG) {
//Paint debug shapes
g2d.setStroke(new BasicStroke(0));
g2d.setColor(Color.LIGHT_GRAY);
g2d.draw(debugShapes);
}
}

/** {@inheritDoc} */
@Override
protected void paintTextRuns(List textRuns, Graphics2D g2d) {
protected void paintTextRuns(@SuppressWarnings("rawtypes") List textRuns, Graphics2D g2d) {
if (log.isTraceEnabled()) {
log.trace("paintTextRuns: count = " + textRuns.size());
}
@@ -81,7 +185,7 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
return;
}
for (int i = 0; i < textRuns.size(); i++) {
TextRun textRun = (TextRun)textRuns.get(i);
TextRun textRun = (TextRun) textRuns.get(i);
try {
paintTextRun(textRun, g2d);
} catch (IOException ioe) {
@@ -91,16 +195,6 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
}
}

/**
* Finds an array of suitable fonts for a given AttributedCharacterIterator.
* @param aci the character iterator
* @return the array of fonts
*/
protected Font[] findFonts(AttributedCharacterIterator aci) {
Font[] fonts = ACIUtils.findFontsForBatikACI(aci, fontInfo);
return fonts;
}

/**
* Collects all characters from an {@link AttributedCharacterIterator}.
* @param runaci the character iterator
@@ -115,6 +209,25 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
return chars;
}

protected abstract void preparePainting(Graphics2D g2d);

protected abstract void saveGraphicsState() throws IOException;

protected abstract void restoreGraphicsState() throws IOException;

protected abstract void setInitialTransform(AffineTransform transform) throws IOException;

protected abstract void clip(Shape clip) throws IOException;

protected abstract void beginTextObject() throws IOException;

protected abstract void endTextObject() throws IOException;

protected abstract void positionGlyph(Point2D prevPos, Point2D glyphPos, boolean reposition);

protected abstract void writeGlyph(char glyph, AffineTransform transform) throws IOException;


/**
* @param runaci an attributed character iterator
* @param layout a text span layout
@@ -155,5 +268,9 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
}
}

@Override
protected FontFamilyResolver getFontFamilyResolver() {
return this.fontFamilyResolver;
}

}

+ 84
- 145
src/java/org/apache/fop/svg/PDFTextPainter.java View File

@@ -19,25 +19,17 @@

package org.apache.fop.svg;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.text.AttributedCharacterIterator;

import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.batik.gvt.text.TextSpanLayout;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.util.CharUtilities;

/**
* Renders the attributed character iterator of a {@link org.apache.batik.gvt.TextNode}.
@@ -51,11 +43,19 @@ import org.apache.fop.util.CharUtilities;
*/
class PDFTextPainter extends NativeTextPainter {

private static final boolean DEBUG = false;
private PDFGraphics2D pdf;

private PDFTextUtil textUtil;

private double prevVisibleGlyphWidth;

private boolean repositionNextGlyph;

/**
* Create a new PDF text painter with the given font information.
*
* @param fi the font info
* @param fontFamilyResolver the Font Family Resolver
*/
public PDFTextPainter(FontInfo fi) {
super(fi);
@@ -67,29 +67,29 @@ class PDFTextPainter extends NativeTextPainter {
return g2d instanceof PDFGraphics2D;
}

/** {@inheritDoc} */
@Override
protected void paintTextRun(TextRun textRun, Graphics2D g2d) {
AttributedCharacterIterator runaci = textRun.getACI();
runaci.first();
protected void preparePainting(Graphics2D g2d) {
pdf = (PDFGraphics2D) g2d;
}

TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
if (tpi == null || !tpi.visible) {
return;
}
if ((tpi != null) && (tpi.composite != null)) {
g2d.setComposite(tpi.composite);
}
@Override
protected void saveGraphicsState() {
pdf.saveGraphicsState();
}

//------------------------------------
TextSpanLayout layout = textRun.getLayout();
logTextRun(runaci, layout);
CharSequence chars = collectCharacters(runaci);
runaci.first(); //Reset ACI
@Override
protected void restoreGraphicsState() {
pdf.restoreGraphicsState();
}

final PDFGraphics2D pdf = (PDFGraphics2D)g2d;
@Override
protected void setInitialTransform(AffineTransform transform) {
createTextUtil();
textUtil.concatMatrix(transform);
}

PDFTextUtil textUtil = new PDFTextUtil(pdf.fontInfo) {
private void createTextUtil() {
textUtil = new PDFTextUtil(pdf.fontInfo) {
protected void write(String code) {
pdf.currentStream.write(code);
}
@@ -97,142 +97,39 @@ class PDFTextPainter extends NativeTextPainter {
pdf.currentStream.append(code);
}
};
}

if (DEBUG) {
log.debug("Text: " + chars);
pdf.currentStream.write("%Text: " + chars + "\n");
}

GeneralPath debugShapes = null;
if (DEBUG) {
debugShapes = new GeneralPath();
}

Font[] fonts = findFonts(runaci);
if (fonts == null || fonts.length == 0) {
//Draw using Java2D when no native fonts are available
textRun.getLayout().draw(g2d);
return;
}

pdf.saveGraphicsState();
textUtil.concatMatrix(g2d.getTransform());
Shape imclip = g2d.getClip();
pdf.writeClip(imclip);

applyColorAndPaint(tpi, pdf);
@Override
protected void clip(Shape clip) {
pdf.writeClip(clip);
}

@Override
protected void beginTextObject() {
applyColorAndPaint(tpi);
textUtil.beginTextObject();
textUtil.setFonts(fonts);
boolean stroke = (tpi.strokePaint != null)
&& (tpi.strokeStroke != null);
boolean stroke = (tpi.strokePaint != null) && (tpi.strokeStroke != null);
textUtil.setTextRenderingMode(tpi.fillPaint != null, stroke, false);
}

AffineTransform localTransform = new AffineTransform();
Point2D prevPos = null;
double prevVisibleCharWidth = 0.0;
GVTGlyphVector gv = layout.getGlyphVector();
for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) {
char ch = chars.charAt(index);
boolean visibleChar = gv.isGlyphVisible(index)
|| (CharUtilities.isAnySpace(ch) && !CharUtilities.isZeroWidthSpace(ch));
logCharacter(ch, layout, index, visibleChar);
if (!visibleChar) {
continue;
}
Point2D glyphPos = gv.getGlyphPosition(index);

AffineTransform glyphTransform = gv.getGlyphTransform(index);
//TODO Glyph transforms could be refined so not every char has to be painted
//with its own TJ command (stretch/squeeze case could be optimized)
if (log.isTraceEnabled()) {
log.trace("pos " + glyphPos + ", transform " + glyphTransform);
}
if (DEBUG) {
Shape sh = gv.getGlyphLogicalBounds(index);
if (sh == null) {
sh = new Ellipse2D.Double(glyphPos.getX(), glyphPos.getY(), 2, 2);
}
debugShapes.append(sh, false);
}

//Exact position of the glyph
localTransform.setToIdentity();
localTransform.translate(glyphPos.getX(), glyphPos.getY());
if (glyphTransform != null) {
localTransform.concatenate(glyphTransform);
}
localTransform.scale(1, -1);

boolean yPosChanged = (prevPos == null
|| prevPos.getY() != glyphPos.getY()
|| glyphTransform != null);
if (yPosChanged) {
if (index > 0) {
textUtil.writeTJ();
textUtil.writeTextMatrix(localTransform);
}
} else {
double xdiff = glyphPos.getX() - prevPos.getX();
//Width of previous character
Font font = textUtil.getCurrentFont();
double cw = prevVisibleCharWidth;
double effxdiff = (1000 * xdiff) - cw;
if (effxdiff != 0) {
double adjust = (-effxdiff / font.getFontSize());
textUtil.adjustGlyphTJ(adjust * 1000);
}
if (log.isTraceEnabled()) {
log.trace("==> x diff: " + xdiff + ", " + effxdiff
+ ", charWidth: " + cw);
}
}
Font f = textUtil.selectFontForChar(ch);
char paintChar = (CharUtilities.isAnySpace(ch) ? ' ' : ch);
char mappedChar = f.mapChar(paintChar);
boolean encodingChanging = false; // used for single byte
if (!textUtil.isMultiByteFont(f.getFontName())) {
int encoding = mappedChar / 256;
mappedChar = (char) (mappedChar % 256);
if (textUtil.getCurrentEncoding() != encoding) {
textUtil.setCurrentEncoding(encoding);
encodingChanging = true;
}
}
if (f != textUtil.getCurrentFont() || encodingChanging) {
textUtil.writeTJ();
textUtil.setCurrentFont(f);
textUtil.writeTf(f);
textUtil.writeTextMatrix(localTransform);
}
textUtil.writeTJMappedChar(mappedChar);

//Update last position
prevPos = glyphPos;
prevVisibleCharWidth = textUtil.getCurrentFont().getCharWidth(chars.charAt(index));
}
@Override
protected void endTextObject() {
textUtil.writeTJ();
textUtil.endTextObject();
pdf.restoreGraphicsState();
if (DEBUG) {
g2d.setStroke(new BasicStroke(0));
g2d.setColor(Color.LIGHT_GRAY);
g2d.draw(debugShapes);
}
}

private void applyColorAndPaint(TextPaintInfo tpi, PDFGraphics2D pdf) {
private void applyColorAndPaint(TextPaintInfo tpi) {
Paint fillPaint = tpi.fillPaint;
Paint strokePaint = tpi.strokePaint;
Stroke stroke = tpi.strokeStroke;
int fillAlpha = PDFGraphics2D.OPAQUE;
if (fillPaint instanceof Color) {
Color col = (Color)fillPaint;
Color col = (Color) fillPaint;
pdf.applyColor(col, true);
fillAlpha = col.getAlpha();
}
if (strokePaint instanceof Color) {
Color col = (Color)strokePaint;
Color col = (Color) strokePaint;
pdf.applyColor(col, false);
}
pdf.applyPaint(fillPaint, true);
@@ -243,4 +140,46 @@ class PDFTextPainter extends NativeTextPainter {
pdf.applyAlpha(fillAlpha, PDFGraphics2D.OPAQUE);
}

@Override
protected void positionGlyph(Point2D prevPos, Point2D glyphPos, boolean reposition) {
// TODO Glyph transforms could be refined so not every char has to be painted
// with its own TJ command (stretch/squeeze case could be optimized)
repositionNextGlyph = (prevPos == null
|| prevPos.getY() != glyphPos.getY()
|| reposition);
if (!repositionNextGlyph) {
double xdiff = glyphPos.getX() - prevPos.getX();
//Width of previous character
double cw = prevVisibleGlyphWidth;
double effxdiff = (1000 * xdiff) - cw;
if (effxdiff != 0) {
double adjust = (-effxdiff / font.getFontSize());
textUtil.adjustGlyphTJ(adjust * 1000);
}
}
}

@Override
protected void writeGlyph(char glyph, AffineTransform transform) {
prevVisibleGlyphWidth = font.getWidth(glyph);
boolean encodingChanging = false; // used for single byte
if (!textUtil.isMultiByteFont(font.getFontName())) {
int encoding = glyph / 256;
glyph = (char) (glyph % 256);
if (textUtil.getCurrentEncoding() != encoding) {
textUtil.setCurrentEncoding(encoding);
encodingChanging = true;
}
}
if (repositionNextGlyph || encodingChanging) {
textUtil.writeTJ();
if (font != textUtil.getCurrentFont() || encodingChanging) {
textUtil.setCurrentFont(font);
textUtil.writeTf(font);
}
textUtil.writeTextMatrix(transform);
}
textUtil.writeTJMappedChar(glyph);
}

}

+ 0
- 41
src/java/org/apache/fop/svg/PDFTextUtil.java View File

@@ -30,7 +30,6 @@ import org.apache.fop.fonts.Typeface;
public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil {

private FontInfo fontInfo;
private Font[] fonts;
private Font font;
private int encoding;

@@ -49,23 +48,6 @@ public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil {
this.font = null;
}

/**
* Sets the current fonts for the text object. For every character, the suitable font will
* be selected.
* @param fonts the new fonts
*/
public void setFonts(Font[] fonts) {
this.fonts = fonts;
}

/**
* Sets the current font for the text object.
* @param font the new font
*/
public void setFont(Font font) {
setFonts(new Font[] {font});
}

/**
* Returns the current font in use.
* @return the current font or null if no font is currently active.
@@ -123,27 +105,4 @@ public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil {
}
}

/**
* Selects a font from the font list suitable to display the given character.
* @param ch the character
* @return the recommended Font to use
*/
public Font selectFontForChar(char ch) {
for (int i = 0, c = fonts.length; i < c; i++) {
if (fonts[i].hasChar(ch)) {
return fonts[i];
}
}
return fonts[0]; //TODO Maybe fall back to painting with shapes
}

/**
* Writes a char to the "TJ-Buffer".
* @param ch the unmapped character
*/
public void writeTJChar(char ch) {
char mappedChar = font.mapChar(ch);
writeTJMappedChar(mappedChar);
}

}

+ 4
- 2
src/java/org/apache/fop/svg/PDFTranscoder.java View File

@@ -31,7 +31,6 @@ import org.apache.avalon.framework.configuration.Configuration;

import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.UnitProcessor;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.ext.awt.RenderingHintsKeyExt;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderOutput;
@@ -39,6 +38,7 @@ import org.apache.batik.transcoder.image.ImageTranscoder;

import org.apache.fop.Version;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;

/**
* <p>This class enables to transcode an input to a PDF document.</p>
@@ -88,7 +88,7 @@ public class PDFTranscoder extends AbstractFOPTranscoder {
/**
* {@inheritDoc}
*/
protected UserAgent createUserAgent() {
protected FOPTranscoderUserAgent createUserAgent() {
return new AbstractFOPTranscoder.FOPTranscoderUserAgent() {
// The PDF stuff wants everything at 72dpi
public float getPixelUnitToMillimeter() {
@@ -131,6 +131,8 @@ public class PDFTranscoder extends AbstractFOPTranscoder {
} else {
graphics.setupDefaultFontInfo();
}
((FOPTranscoderUserAgent) userAgent).setFontFamilyResolver(
new FOPFontFamilyResolverImpl(graphics.getFontInfo()));
} catch (Exception e) {
throw new TranscoderException(
"Error while setting up PDFDocumentGraphics2D", e);

+ 7
- 4
src/java/org/apache/fop/svg/SVGUserAgent.java View File

@@ -21,6 +21,8 @@ package org.apache.fop.svg;

import java.awt.geom.AffineTransform;

import org.apache.batik.gvt.font.FontFamilyResolver;

import org.apache.fop.apps.FOUserAgent;

/**
@@ -34,10 +36,11 @@ public class SVGUserAgent extends SimpleSVGUserAgent {
/**
* Creates a new SVGUserAgent.
* @param foUserAgent the FO user agent to associate with this SVG user agent
* @param fontFamilyResolver the font family resolver
* @param at the current transform
*/
public SVGUserAgent(FOUserAgent foUserAgent, AffineTransform at) {
super(foUserAgent.getSourcePixelUnitToMillimeter(), at);
public SVGUserAgent(FOUserAgent foUserAgent, FontFamilyResolver fontFamilyResolver, AffineTransform at) {
super(foUserAgent.getSourcePixelUnitToMillimeter(), at, fontFamilyResolver);
this.eventProducer = SVGEventProducer.Provider.get(foUserAgent.getEventBroadcaster());
}

@@ -45,8 +48,8 @@ public class SVGUserAgent extends SimpleSVGUserAgent {
* Creates a new SVGUserAgent.
* @param foUserAgent the FO user agent to associate with this SVG user agent
*/
public SVGUserAgent(FOUserAgent foUserAgent) {
this(foUserAgent, new AffineTransform());
public SVGUserAgent(FOUserAgent foUserAgent, FontFamilyResolver fontFamilyResolver) {
this(foUserAgent, fontFamilyResolver, new AffineTransform());
}

/**

+ 11
- 1
src/java/org/apache/fop/svg/SimpleSVGUserAgent.java View File

@@ -26,6 +26,7 @@ import java.awt.geom.Dimension2D;
import javax.xml.parsers.SAXParserFactory;

import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.gvt.font.FontFamilyResolver;

/**
* A simple SVG user agent.
@@ -35,14 +36,18 @@ import org.apache.batik.bridge.UserAgentAdapter;
public class SimpleSVGUserAgent extends UserAgentAdapter {

private AffineTransform currentTransform = null;

private float pixelUnitToMillimeter = 0.0f;

private final FontFamilyResolver fontFamilyResolver;

/**
* Creates a new user agent.
* @param pixelUnitToMM the pixel to millimeter conversion factor currently in effect
* @param at the current transform
*/
public SimpleSVGUserAgent(float pixelUnitToMM, AffineTransform at) {
public SimpleSVGUserAgent(float pixelUnitToMM, AffineTransform at, FontFamilyResolver fontFamilyResolver) {
this.fontFamilyResolver = fontFamilyResolver;
pixelUnitToMillimeter = pixelUnitToMM;
currentTransform = at;
}
@@ -122,5 +127,10 @@ public class SimpleSVGUserAgent extends UserAgentAdapter {
return new Dimension(100, 100);
}

@Override
public FontFamilyResolver getFontFamilyResolver() {
return fontFamilyResolver;
}

}


+ 70
- 0
src/java/org/apache/fop/svg/font/AggregatingFontFamilyResolver.java View File

@@ -0,0 +1,70 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.util.Arrays;
import java.util.List;

import org.apache.batik.gvt.font.FontFamilyResolver;
import org.apache.batik.gvt.font.GVTFontFamily;

public class AggregatingFontFamilyResolver implements FontFamilyResolver {

private final List<FontFamilyResolver> resolvers;

public AggregatingFontFamilyResolver(FontFamilyResolver... resolvers) {
this.resolvers = Arrays.<FontFamilyResolver>asList(resolvers);
}

public String lookup(String familyName) {
for (FontFamilyResolver resolver : resolvers) {
String lookup = resolver.lookup(familyName);
if (lookup != null) {
return lookup;
}
}
return null;
}

public GVTFontFamily resolve(String familyName) {
for (FontFamilyResolver resolver : resolvers) {
GVTFontFamily family = resolver.resolve(familyName);
if (family != null) {
return family;
}
}
return null;
}

public GVTFontFamily getDefault() {
return resolve("any");
}

public GVTFontFamily getFamilyThatCanDisplay(char c) {
for (FontFamilyResolver resolver : resolvers) {
GVTFontFamily family = resolver.getFamilyThatCanDisplay(c);
if (family != null) {
return family;
}
}
return null;
}

}

+ 31
- 0
src/java/org/apache/fop/svg/font/FOPFontFamilyResolver.java View File

@@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import org.apache.batik.gvt.font.FontFamilyResolver;

public interface FOPFontFamilyResolver extends FontFamilyResolver {

FOPGVTFontFamily resolve(String familyName);

FOPGVTFontFamily getDefault();

FOPGVTFontFamily getFamilyThatCanDisplay(char c);
}

+ 67
- 0
src/java/org/apache/fop/svg/font/FOPFontFamilyResolverImpl.java View File

@@ -0,0 +1,67 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.util.Map;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.Typeface;

public class FOPFontFamilyResolverImpl implements FOPFontFamilyResolver {

private final FontInfo fontInfo;

public FOPFontFamilyResolverImpl(FontInfo fontInfo) {
this.fontInfo = fontInfo;
}

public String lookup(String familyName) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}

public FOPGVTFontFamily resolve(String familyName) {
FOPGVTFontFamily gvtFontFamily = null;
FontTriplet triplet = fontInfo.fontLookup(familyName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
if (fontInfo.hasFont(familyName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL)) {
gvtFontFamily = new FOPGVTFontFamily(fontInfo, familyName, triplet);
}
return gvtFontFamily;
}

public FOPGVTFontFamily getDefault() {
return resolve("any");
}

public FOPGVTFontFamily getFamilyThatCanDisplay(char c) {
Map<String, Typeface> fonts = fontInfo.getFonts();
for (Typeface font : fonts.values()) {
if (font.hasChar(c)) {
String fontFamily = font.getFamilyNames().iterator().next();
return new FOPGVTFontFamily(fontInfo, fontFamily,
new FontTriplet(fontFamily, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL));
}
}
return null;
}

}

+ 159
- 0
src/java/org/apache/fop/svg/font/FOPGVTFont.java View File

@@ -0,0 +1,159 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.awt.font.FontRenderContext;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;

import org.apache.batik.gvt.font.GVTFont;
import org.apache.batik.gvt.font.GVTFontFamily;
import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.font.GVTLineMetrics;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontMetrics;

public class FOPGVTFont implements GVTFont {

private final Font font;

private final GVTFontFamily fontFamily;

public FOPGVTFont(Font font, GVTFontFamily fontFamily) {
this.font = font;
this.fontFamily = fontFamily;
}

public Font getFont() {
return font;
}

public boolean canDisplay(char c) {
return font.hasChar(c);
}

public int canDisplayUpTo(char[] text, int start, int limit) {
for (int i = start; i < limit; i++) {
if (!canDisplay(text[i])) {
return i;
}
}
return -1;
}


public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
for (char c = iter.setIndex(start); iter.getIndex() < limit; c = iter.next()) {
if (!canDisplay(c)) {
return iter.getIndex();
}
}
return -1;
}

public int canDisplayUpTo(String str) {
for (int i = 0; i < str.length(); i++) {
if (!canDisplay(str.charAt(i))) {
return i;
}
}
return -1;
}

public GVTGlyphVector createGlyphVector(FontRenderContext frc, char[] chars) {
return createGlyphVector(frc, new String(chars));
}

public GVTGlyphVector createGlyphVector(FontRenderContext frc, CharacterIterator ci) {
// TODO Batik does manual glyph shaping for Arabic. Replace with complex scripts implementation
return new FOPGVTGlyphVector(this, ci, frc);
}

public GVTGlyphVector createGlyphVector(FontRenderContext frc,
int[] glyphCodes,
CharacterIterator ci) {
throw new UnsupportedOperationException("Not implemented");
}

public GVTGlyphVector createGlyphVector(FontRenderContext frc, String str) {
StringCharacterIterator sci = new StringCharacterIterator(str);
return createGlyphVector(frc, sci);
}

public FOPGVTFont deriveFont(float size) {
throw new UnsupportedOperationException("Not implemented");
}

public String getFamilyName() {
return fontFamily.getFamilyName();
}

public GVTLineMetrics getLineMetrics(char[] chars, int beginIndex, int limit, FontRenderContext frc) {
return getLineMetrics(limit - beginIndex);
}

GVTLineMetrics getLineMetrics(int numChars) {
numChars = numChars < 0 ? 0 : numChars;
FontMetrics metrics = font.getFontMetrics();
int size = font.getFontSize();
return new GVTLineMetrics(
metrics.getCapHeight(size) / 1000000f,
java.awt.Font.ROMAN_BASELINE, // Not actually used by Batik
null, // Not actually used by Batik
-metrics.getDescender(size) / 1000000f,
0, // Not actually used by Batik
0, // Not actually used by Batik
numChars,
-metrics.getStrikeoutPosition(size) / 1000000f,
metrics.getStrikeoutThickness(size) / 1000000f,
-metrics.getUnderlinePosition(size) / 1000000f,
metrics.getUnderlineThickness(size) / 1000000f,
-metrics.getCapHeight(size) / 1000000f, // Because this is what Batik does in GVTLineMetrics
metrics.getUnderlineThickness(size) / 1000000f);
}

public GVTLineMetrics getLineMetrics(CharacterIterator ci, int beginIndex, int limit,
FontRenderContext frc) {
return getLineMetrics(limit - beginIndex);
}

public GVTLineMetrics getLineMetrics(String str, FontRenderContext frc) {
return getLineMetrics(str.length());
}

public GVTLineMetrics getLineMetrics(String str, int beginIndex, int limit, FontRenderContext frc) {
return getLineMetrics(limit - beginIndex);
}

public float getSize() {
return font.getFontSize() / 1000f;
}

public float getVKern(int glyphCode1, int glyphCode2) {
return 0;
}

public float getHKern(int glyphCode1, int glyphCode2) {
// TODO Cannot be implemented until getKernValue takes glyph indices instead of character codes
return 0;
}

}

+ 73
- 0
src/java/org/apache/fop/svg/font/FOPGVTFontFamily.java View File

@@ -0,0 +1,73 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.awt.font.TextAttribute;
import java.text.AttributedCharacterIterator;
import java.util.Map;

import org.apache.batik.gvt.font.GVTFontFace;
import org.apache.batik.gvt.font.GVTFontFamily;

import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.svg.ACIUtils;

public class FOPGVTFontFamily implements GVTFontFamily {

private final FontInfo fontInfo;

private final FontTriplet fontTriplet;

private final String familyName;

public FOPGVTFontFamily(FontInfo fontInfo, String familyName, FontTriplet triplet) {
this.fontInfo = fontInfo;
this.fontTriplet = triplet;
this.familyName = familyName;
}

public String getFamilyName() {
return familyName;
}

public GVTFontFace getFontFace() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}

public FOPGVTFont deriveFont(float size, AttributedCharacterIterator aci) {
return deriveFont(size, aci.getAttributes());
}

public FOPGVTFont deriveFont(float size, @SuppressWarnings("rawtypes") Map attrs) {
Float fontWeight = (Float) attrs.get(TextAttribute.WEIGHT);
int weight = fontWeight == null ? fontTriplet.getWeight() : ACIUtils.toCSSWeight(fontWeight);
Float fontStyle = (Float) attrs.get(TextAttribute.POSTURE);
String style = fontStyle == null ? fontTriplet.getStyle() : ACIUtils.toStyle(fontStyle);
FontTriplet triplet = fontInfo.fontLookup(fontTriplet.getName(), style, weight);
return new FOPGVTFont(fontInfo.getFontInstance(triplet, (int) (size * 1000)), this);
}

public boolean isComplex() {
return false;
}

}

+ 339
- 0
src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java View File

@@ -0,0 +1,339 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphJustificationInfo;
import java.awt.font.GlyphMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.text.AttributedCharacterIterator;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.Arrays;

import org.apache.batik.gvt.font.GVTFont;
import org.apache.batik.gvt.font.GVTGlyphMetrics;
import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.font.GVTLineMetrics;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontMetrics;
import org.apache.fop.fonts.GlyphMapping;
import org.apache.fop.fonts.TextFragment;
import org.apache.fop.traits.MinOptMax;

class FOPGVTGlyphVector implements GVTGlyphVector {

private final CharacterIterator charIter;

private final FOPGVTFont font;

private final int fontSize;

private final FontMetrics fontMetrics;

private final FontRenderContext frc;

private int[] glyphs;

private float[] positions;

private Rectangle2D[] boundingBoxes;

private GeneralPath outline;

private AffineTransform[] glyphTransforms;

private boolean[] glyphVisibilities;

private Rectangle2D logicalBounds;

FOPGVTGlyphVector(FOPGVTFont font, final CharacterIterator iter, FontRenderContext frc) {
this.charIter = iter;
this.font = font;
Font f = font.getFont();
this.fontSize = f.getFontSize();
this.fontMetrics = f.getFontMetrics();
this.frc = frc;
}

public void performDefaultLayout() {
Font f = font.getFont();
TextFragment text = new SVGTextFragment(charIter);
MinOptMax letterSpaceIPD = MinOptMax.ZERO;
MinOptMax[] letterSpaceAdjustments = new MinOptMax[charIter.getEndIndex() - charIter.getBeginIndex()];
GlyphMapping mapping = GlyphMapping.doGlyphMapping(text, charIter.getBeginIndex(), charIter.getEndIndex(),
f, letterSpaceIPD, letterSpaceAdjustments, '\0', '\0', false, 0 /* TODO */);
glyphs = buildGlyphs(f, mapping.mapping != null ? new StringCharacterIterator(mapping.mapping) : charIter);
buildGlyphPositions(mapping, letterSpaceAdjustments);
this.glyphVisibilities = new boolean[this.glyphs.length];
Arrays.fill(glyphVisibilities, true);
this.glyphTransforms = new AffineTransform[this.glyphs.length];
}

private static class SVGTextFragment implements TextFragment {

private final CharacterIterator charIter;

SVGTextFragment(CharacterIterator charIter) {
this.charIter = charIter;
}

public CharSequence subSequence(int startIndex, int endIndex) {
StringBuilder sb = new StringBuilder();
for (char c = charIter.first(); c != CharacterIterator.DONE; c = charIter.next()) {
sb.append(c);
}
return sb.toString();
}

public String getScript() {
return "DFLT"; // TODO pass on script value from SVG
}

public String getLanguage() {
return "dflt"; // TODO pass on language value from SVG
}

public char charAt(int index) {
return charIter.setIndex(index - charIter.getBeginIndex());
}
}

private int[] buildGlyphs(Font font, final CharacterIterator charIter) {
int[] glyphs = new int[charIter.getEndIndex() - charIter.getBeginIndex()];
int index = 0;
for (char c = charIter.first(); c != CharacterIterator.DONE; c = charIter.next()) {
glyphs[index] = font.mapChar(c);
index++;
}
return glyphs;
}

private void buildGlyphPositions(GlyphMapping ai, MinOptMax[] letterSpaceAdjustments) {
positions = new float[2 * glyphs.length + 2];
if (ai.gposAdjustments != null) {
assert ai.gposAdjustments.length == glyphs.length;
for (int glyphIndex = 0; glyphIndex < glyphs.length; glyphIndex++) {
int n = 2 * glyphIndex;
if (ai.gposAdjustments[glyphIndex] != null) {
for (int p = 0; p < 4; p++) {
positions[n + p] += ai.gposAdjustments[glyphIndex][p] / 1000f;
}
}
positions[n + 2] += positions[n] + getGlyphWidth(glyphIndex);
}
} else {
for (int i = 0, n = 2; i < glyphs.length; i++, n += 2) {
int kern = i < glyphs.length - 1 && letterSpaceAdjustments[i + 1] != null
? letterSpaceAdjustments[i + 1].getOpt()
: 0;
positions[n] = positions[n - 2] + getGlyphWidth(i) + kern / 1000f;
positions[n + 1] = 0;
}
}
}

private float getGlyphWidth(int index) {
return fontMetrics.getWidth(glyphs[index], fontSize) / 1000000f;
}

public GVTFont getFont() {
return font;
}

public FontRenderContext getFontRenderContext() {
return frc;
}

public int getGlyphCode(int glyphIndex) {
return glyphs[glyphIndex];
}

public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
int[] codeReturn) {
if (codeReturn == null) {
codeReturn = new int[numEntries];
}
System.arraycopy(glyphs, beginGlyphIndex, codeReturn, 0, numEntries);
return codeReturn;
}

public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}

public Shape getGlyphLogicalBounds(int glyphIndex) {
GVTGlyphMetrics metrics = getGlyphMetrics(glyphIndex);
Point2D pos = getGlyphPosition(glyphIndex);
GVTLineMetrics fontMetrics = font.getLineMetrics(0);
Rectangle2D bounds = new Rectangle2D.Float(0, -fontMetrics.getDescent(), metrics.getHorizontalAdvance(),
fontMetrics.getAscent() + fontMetrics.getDescent());
AffineTransform t = AffineTransform.getTranslateInstance(pos.getX(), pos.getY());
AffineTransform transf = getGlyphTransform(glyphIndex);
if (transf != null) {
t.concatenate(transf);
}
t.scale(1, -1); // Translate from glyph coordinate system to user
return t.createTransformedShape(bounds);
}

public GVTGlyphMetrics getGlyphMetrics(int glyphIndex) {
Rectangle2D bbox = getBoundingBoxes()[glyphIndex];
return new GVTGlyphMetrics(positions[2 * (glyphIndex + 1)] - positions[2 * glyphIndex],
(fontMetrics.getAscender(fontSize) - fontMetrics.getDescender(fontSize)) / 1000000f,
bbox, GlyphMetrics.STANDARD);
}

public Shape getGlyphOutline(int glyphIndex) {
Shape glyphBox = getBoundingBoxes()[glyphIndex];
AffineTransform tr = AffineTransform.getTranslateInstance(positions[glyphIndex * 2],
positions[glyphIndex * 2 + 1]);
AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
if (glyphTransform != null) {
tr.concatenate(glyphTransform);
}
return tr.createTransformedShape(glyphBox);
}

public Rectangle2D getGlyphCellBounds(int glyphIndex) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}

public Point2D getGlyphPosition(int glyphIndex) {
int positionIndex = glyphIndex * 2;
return new Point2D.Float(positions[positionIndex], positions[positionIndex + 1]);
}

public float[] getGlyphPositions(int beginGlyphIndex, int numEntries, float[] positionReturn) {
if (positionReturn == null) {
positionReturn = new float[numEntries * 2];
}
System.arraycopy(positions, beginGlyphIndex * 2, positionReturn, 0, numEntries * 2);
return positionReturn;
}

public AffineTransform getGlyphTransform(int glyphIndex) {
return glyphTransforms[glyphIndex];
}

public Shape getGlyphVisualBounds(int glyphIndex) {
Rectangle2D bbox = getBoundingBoxes()[glyphIndex];
Point2D pos = getGlyphPosition(glyphIndex);
AffineTransform t = AffineTransform.getTranslateInstance(pos.getX(), pos.getY());
AffineTransform transf = getGlyphTransform(glyphIndex);
if (transf != null) {
t.concatenate(transf);
}
return t.createTransformedShape(bbox);
}

public Rectangle2D getLogicalBounds() {
if (logicalBounds == null) {
GeneralPath logicalBoundsPath = new GeneralPath();
for (int i = 0; i < getNumGlyphs(); i++) {
Shape glyphLogicalBounds = getGlyphLogicalBounds(i);
logicalBoundsPath.append(glyphLogicalBounds, false);
}
logicalBounds = logicalBoundsPath.getBounds2D();
}
return logicalBounds;
}

public int getNumGlyphs() {
return glyphs.length;
}

public Shape getOutline() {
if (outline == null) {
outline = new GeneralPath();
for (int i = 0; i < glyphs.length; i++) {
outline.append(getGlyphOutline(i), false);
}
}
return outline;
}

public Shape getOutline(float x, float y) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}

public Rectangle2D getGeometricBounds() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}

public Rectangle2D getBounds2D(AttributedCharacterIterator aci) {
return getOutline().getBounds2D();
}

public void setGlyphPosition(int glyphIndex, Point2D newPos) {
int idx = glyphIndex * 2;
positions[idx] = (float) newPos.getX();
positions[idx + 1] = (float) newPos.getY();
}

public void setGlyphTransform(int glyphIndex, AffineTransform newTX) {
glyphTransforms[glyphIndex] = newTX;
}

public void setGlyphVisible(int glyphIndex, boolean visible) {
glyphVisibilities[glyphIndex] = visible;
}

public boolean isGlyphVisible(int glyphIndex) {
return glyphVisibilities[glyphIndex];
}

public int getCharacterCount(int startGlyphIndex, int endGlyphIndex) {
// TODO Not that simple if complex scripts are involved
return endGlyphIndex - startGlyphIndex + 1;
}

public void draw(Graphics2D graphics2d, AttributedCharacterIterator aci) {
// NOP
}

private Rectangle2D[] getBoundingBoxes() {
if (boundingBoxes == null) {
buildBoundingBoxes();
}
return boundingBoxes;
}

private void buildBoundingBoxes() {
boundingBoxes = new Rectangle2D[glyphs.length];
for (int i = 0; i < glyphs.length; i++) {
Rectangle bbox = fontMetrics.getBoundingBox(glyphs[i], fontSize);
boundingBoxes[i] = new Rectangle2D.Float(bbox.x / 1000000f, -(bbox.y + bbox.height) / 1000000f,
bbox.width / 1000000f, bbox.height / 1000000f);
}
}

}

+ 47
- 0
src/java/org/apache/fop/svg/font/FilteringFontFamilyResolver.java View File

@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;


public class FilteringFontFamilyResolver implements FOPFontFamilyResolver {

private final FOPFontFamilyResolver delegate;

public FilteringFontFamilyResolver(FOPFontFamilyResolver delegate) {
this.delegate = delegate;
}

public String lookup(String familyName) {
return delegate.lookup(familyName);
}

public FOPGVTFontFamily resolve(String familyName) {
return delegate.resolve(familyName);
}

public FOPGVTFontFamily getDefault() {
return delegate.getDefault();
}

public FOPGVTFontFamily getFamilyThatCanDisplay(char c) {
return delegate.getFamilyThatCanDisplay(c);
}

}

+ 48
- 0
test/java/org/apache/fop/afp/fonts/IntegerKeyStoreTestCase.java View File

@@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.afp.fonts;

import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

public class IntegerKeyStoreTestCase {

@Test
public void getAndPut() {
IntegerKeyStore<Integer> sut = new IntegerKeyStore<Integer>();
assertNull(sut.get(0));
sut.put(0, 0);
assertEquals(Integer.valueOf(0), sut.get(0));
sut.put(0, 1);
assertEquals(Integer.valueOf(1), sut.get(0));
sut.put(0, null);
assertNull(sut.get(0));
try {
sut.put(-1, 0);
fail("Negative index");
} catch (IndexOutOfBoundsException e) {
// As expected
}
}

}

+ 15
- 2
test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java View File

@@ -24,11 +24,11 @@ import java.io.File;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.apps.io.ResourceResolverFactory;

import static org.junit.Assert.assertEquals;

/**
*
*/
@@ -58,4 +58,17 @@ public class DejaVuLGCSerifTestCase {
public void testFontName() {
assertEquals("DejaVuLGCSerif", font.getFontName());
}

@Test
public void testUnderline() {
assertEquals(-840, font.getUnderlinePosition(10));
assertEquals(430, font.getUnderlineThickness(10));
}

@Test
public void testStrikeout() {
assertEquals(2340, font.getStrikeoutPosition(10));
assertEquals(490, font.getStrikeoutThickness(10));
}

}

+ 0
- 9
test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java View File

@@ -52,13 +52,4 @@ public class FontEventProcessingTestCase {
MimeConstants.MIME_PDF);
}

@Test
public void testSVGFontStrokedAsShapes() throws Exception {
// svg-fonts.fo embeds two fonts; one that is present in the system and the other is not; the
// missing font is stroked as shapes while the fonts that exists is stroked as text
InputStream inStream = getClass().getResourceAsStream("svg-fonts.fo");
eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".svgTextStrokedAsShapes",
MimeConstants.MIME_PDF);
}

}

+ 0
- 37
test/java/org/apache/fop/fonts/svg-fonts.fo View File

@@ -1,37 +0,0 @@
<?xml version="1.0" standalone="no"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
<fo:layout-master-set>
<fo:simple-page-master master-name="page">
<fo:region-body />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="page">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:instream-foreign-object>
<svg:svg width="250" height="50">
<svg:font horiz-adv-x="1000">
<svg:font-face font-family="Missing" units-per-em="1000" underline-position="-100"
underline-thickness="50" />
<svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" />
<svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" />
<svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" />
<svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" />
</svg:font>
<svg:font horiz-adv-x="1000">
<!-- this is not Helvetica but it is here to increase coverage and show the code takes expected path -->
<svg:font-face font-family="Helvetica" units-per-em="1000" underline-position="-100"
underline-thickness="50" />
<svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" />
<svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" />
<svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" />
<svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" />
</svg:font>
<svg:text x="20" y="20" font-family="Missing" font-size="12">ACFG</svg:text>
<svg:text x="20" y="40" font-family="Helvetica" font-size="12">ACFG</svg:text>
</svg:svg>
</fo:instream-foreign-object>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>

+ 20
- 2
test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java View File

@@ -26,12 +26,12 @@ import java.util.Map;

import org.junit.Test;

import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;

/**
* Class for testing org.apache.fop.fonts.truetype.TTFFile
*/
@@ -426,6 +426,24 @@ public class TTFFileTestCase {
assertEquals(true, droidmonoTTFFile.isEmbeddable());
}

/** Underline position and thickness. */
@Test
public void testUnderline() {
assertEquals(-63, dejavuTTFFile.getUnderlinePosition());
assertEquals(43, dejavuTTFFile.getUnderlineThickness());
assertEquals(-75, droidmonoTTFFile.getUnderlinePosition());
assertEquals(49, droidmonoTTFFile.getUnderlineThickness());
}

/** Strikeout position and thickness. */
@Test
public void testStrikeout() {
assertEquals(258, dejavuTTFFile.getStrikeoutPosition());
assertEquals(49, dejavuTTFFile.getStrikeoutThickness());
assertEquals(243, droidmonoTTFFile.getStrikeoutPosition());
assertEquals(49, droidmonoTTFFile.getStrikeoutThickness());
}

/**
* Test readFont() - Add implementation if necessary.
*/

+ 12
- 3
test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java View File

@@ -19,9 +19,6 @@

package org.apache.fop.fonts.type1;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
@@ -29,6 +26,9 @@ import java.util.List;

import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
* Test case for {@link AFMParser}.
*/
@@ -128,4 +128,13 @@ public class AFMParserTestCase {
private boolean objectEquals(Object o1, Object o2) {
return o1 == null ? o2 == null : (o1 == o2 || o1.equals(o2));
}

@Test
public void testUnderlinePositionAndThickness() throws IOException {
AFMFile afm = sut.parse(getClass().getResourceAsStream("underline.afm"), null);
AFMWritingDirectionMetrics metrics = afm.getWritingDirectionMetrics(0);
assertEquals(-96, metrics.getUnderlinePosition());
assertEquals(58, metrics.getUnderlineThickness());
}

}

+ 4
- 0
test/java/org/apache/fop/fonts/type1/underline.afm View File

@@ -0,0 +1,4 @@
StartFontMetrics 2.0
UnderlinePosition -96
UnderlineThickness 58
EndFontMetrics

+ 78
- 0
test/java/org/apache/fop/svg/NativeTextPainterTest.java View File

@@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.IOException;

import org.w3c.dom.Document;

import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.TextPainter;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.base14.Base14FontCollection;
import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;

abstract class NativeTextPainterTest {

protected final void runTest(String testcase, OperatorValidator validator) throws Exception {
FontInfo fontInfo = createFontInfo();
BridgeContext bridgeContext = createBridgeContext(fontInfo);
GraphicsNode svg = loadSVG(bridgeContext, testcase);
Graphics2D g2d = createGraphics2D(fontInfo, validator);
svg.paint(g2d);
validator.end();
}

private FontInfo createFontInfo() {
FontInfo fontInfo = new FontInfo();
new Base14FontCollection(true).setup(0, fontInfo);
return fontInfo;
}

private BridgeContext createBridgeContext(FontInfo fontInfo) {
FOUserAgent userAgent = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new FOPFontFamilyResolverImpl(fontInfo),
new AffineTransform());
BridgeContext bridgeContext = new BridgeContext(svgUserAgent);
bridgeContext.setTextPainter(createTextPainter(fontInfo));
return bridgeContext;
}

protected abstract TextPainter createTextPainter(FontInfo fontInfo);

private GraphicsNode loadSVG(BridgeContext bridgeContext, String resourceName) throws IOException {
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(null);
Document svg = factory.createDocument(null, getClass().getResourceAsStream(resourceName));
GVTBuilder builder = new GVTBuilder();
return builder.build(bridgeContext, svg);
}

protected abstract Graphics2D createGraphics2D(FontInfo fontInfo, OperatorValidator validator);

}

+ 108
- 0
test/java/org/apache/fop/svg/OperatorValidator.java View File

@@ -0,0 +1,108 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg;

import java.util.LinkedList;
import java.util.Queue;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

class OperatorValidator {

private static interface Match {

boolean match(String line);
}

private static class MatchSequence implements OperatorValidator.Match {

private final Queue<OperatorValidator.Match> expectedMatches = new LinkedList<OperatorValidator.Match>();

private OperatorValidator.Match currentMatch;

private static final OperatorValidator.Match FINAL_MATCH = new Match() {

public boolean match(String line) {
return false;
}
};

public boolean isExhausted() {
return currentMatch == FINAL_MATCH;
}

public void addMatch(OperatorValidator.Match match) {
if (currentMatch == null) {
currentMatch = match;
} else {
expectedMatches.add(match);
}
}

public boolean match(String line) {
boolean match = currentMatch.match(line);
if (match) {
if(expectedMatches.isEmpty()) {
currentMatch = FINAL_MATCH;
} else {
currentMatch = expectedMatches.remove();
}
}
return match;
}
}

private static class OperatorMatch implements OperatorValidator.Match {

final String operator;

final String line;

OperatorMatch(String operator, String line) {
this.operator = operator;
this.line = line;
}

public boolean match(String line) {
if (line.contains(operator)) {
assertEquals(this.line, line);
return true;
}
return false;
}
}

private final OperatorValidator.MatchSequence matchSequence = new MatchSequence();

public OperatorValidator addOperatorMatch(String operator, String expectedLine) {
matchSequence.addMatch(new OperatorMatch(operator, expectedLine));
return this;
}

public void check(String line) {
matchSequence.match(line);
}

public void end() {
assertTrue("Expected operators remain", matchSequence.isExhausted());
}

}

+ 149
- 0
test/java/org/apache/fop/svg/PDFTextPainterTestCase.java View File

@@ -0,0 +1,149 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg;

import java.awt.Graphics2D;
import java.io.StringWriter;

import org.junit.Test;

import org.apache.batik.gvt.TextPainter;

import org.apache.xmlgraphics.java2d.GraphicContext;

import org.apache.fop.fonts.FontInfo;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;

public class PDFTextPainterTestCase extends NativeTextPainterTest {

private static class OperatorCheckingPDFGraphics2D extends PDFGraphics2D {

OperatorCheckingPDFGraphics2D(FontInfo fontInfo, final OperatorValidator validator) {
super(false, fontInfo, new PDFDocument("test"), null, null, null, 0);
this.currentStream = new StringWriter() {

@Override
public void write(String str) {
validator.check(str);
}

};
}
}

@Override
protected TextPainter createTextPainter(FontInfo fontInfo) {
return new PDFTextPainter(fontInfo);
}

@Override
protected Graphics2D createGraphics2D(FontInfo fontInfo, OperatorValidator validator) {
PDFGraphics2D g2d = new OperatorCheckingPDFGraphics2D(fontInfo, validator);
g2d.setGraphicContext(new GraphicContext());
return g2d;
}

@Test
public void testRotatedGlyph() throws Exception {
runTest("rotated-glyph.svg", new OperatorValidator()
.addOperatorMatch("Tm", "1 0 0 -1 40 110 Tm ")
.addOperatorMatch("TJ", "[(A)] TJ\n")
.addOperatorMatch("Tm", "0.70710677 0.7071068 0.7071068 -0.70710677 106.69999695 110 Tm ")
.addOperatorMatch("TJ", "[(B)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 173.3999939 110 Tm ")
.addOperatorMatch("TJ", "[(C)] TJ\n"));
}

@Test
public void testDxDy() throws Exception {
runTest("dx-dy.svg", new OperatorValidator()
.addOperatorMatch("Tm", "1 0 0 -1 55 35 Tm ")
.addOperatorMatch("TJ", "[(ABCDE)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 55 75 Tm ")
.addOperatorMatch("TJ", "[(A)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 69 85 Tm ")
.addOperatorMatch("TJ", "[(B)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 109 80 Tm ")
.addOperatorMatch("TJ", "[(C)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 91 65 Tm ")
.addOperatorMatch("TJ", "[(D)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 127 75 Tm ")
.addOperatorMatch("TJ", "[(E)] TJ\n"));
}

@Test
public void testSpacing() throws Exception {
runTest("spacing.svg", new OperatorValidator()
.addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
.addOperatorMatch("TJ", "[(V) 80 (A) 70 (V)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
.addOperatorMatch("TJ", "[(V) 80 (A) 70 (V)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
.addOperatorMatch("TJ", "[(V) -20 (A) -30 (V)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
.addOperatorMatch("TJ", "[(ab) -111 ( ) -389 (cd)] TJ\n"));
}

@Test
public void testGlyphOrientation() throws Exception {
runTest("glyph-orientation.svg", new OperatorValidator()
.addOperatorMatch("Tm", "0 1 1 0 738.5 0 Tm ")
.addOperatorMatch("TJ", "[(A)] TJ\n")
.addOperatorMatch("Tm", "0 1 1 0 738.5 667 Tm ")
.addOperatorMatch("TJ", "[(B)] TJ\n")
.addOperatorMatch("Tm", "0 1 1 0 738.5 1334 Tm ")
.addOperatorMatch("TJ", "[(C)] TJ\n")
.addOperatorMatch("Tm", "0 1 1 0 738.5 2056 Tm ")
.addOperatorMatch("TJ", "[(D)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 2149 718 Tm ")
.addOperatorMatch("TJ", "[(E)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 2165.5 1643 Tm ")
.addOperatorMatch("TJ", "[(F)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 2124 2568 Tm ")
.addOperatorMatch("TJ", "[(G)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 2138.5 3493 Tm ")
.addOperatorMatch("TJ", "[(H)] TJ\n")
.addOperatorMatch("Tm", "0 -1 -1 0 718 5000 Tm ")
.addOperatorMatch("TJ", "[(I)] TJ\n")
.addOperatorMatch("Tm", "0 -1 -1 0 1643 5000 Tm ")
.addOperatorMatch("TJ", "[(J)] TJ\n")
.addOperatorMatch("Tm", "0 -1 -1 0 2568 5000 Tm ")
.addOperatorMatch("TJ", "[(K)] TJ\n")
.addOperatorMatch("Tm", "0 -1 -1 0 3493 5000 Tm ")
.addOperatorMatch("TJ", "[(L)] TJ\n"));
}

@Test
public void testBaselineShift() throws Exception {
runTest("baseline-shift.svg", new OperatorValidator()
.addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
.addOperatorMatch("TJ", "[(AB)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 1334 -462.5 Tm ")
.addOperatorMatch("TJ", "[(CD)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 2778 0 Tm ")
.addOperatorMatch("TJ", "[(EF)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 4056 462.5 Tm ")
.addOperatorMatch("TJ", "[(GH)] TJ\n")
.addOperatorMatch("Tm", "1 0 0 -1 5556 0 Tm ")
.addOperatorMatch("TJ", "[(IJ)] TJ\n"));
}

}

+ 77
- 0
test/java/org/apache/fop/svg/PSTextPainterTestCase.java View File

@@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg;

import java.awt.Graphics2D;
import java.io.IOException;

import org.junit.Test;

import org.apache.commons.io.output.NullOutputStream;

import org.apache.batik.gvt.TextPainter;

import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
import org.apache.xmlgraphics.ps.PSGenerator;

import org.apache.fop.fonts.FontInfo;
import org.apache.fop.render.ps.PSTextPainter;

public class PSTextPainterTestCase extends NativeTextPainterTest {

private static class OperatorCheckingPSGraphics2D extends PSGraphics2D {

OperatorCheckingPSGraphics2D(FontInfo fontInfo, final OperatorValidator validator) {
super(false, new PSGenerator(new NullOutputStream()) {

@Override
public void writeln(String cmd) throws IOException {
validator.check(cmd);
}

});
}
}

@Override
protected TextPainter createTextPainter(FontInfo fontInfo) {
return new PSTextPainter(fontInfo);
}

@Override
protected Graphics2D createGraphics2D(FontInfo fontInfo, OperatorValidator validator) {
PSGraphics2D g2d = new OperatorCheckingPSGraphics2D(fontInfo, validator);
g2d.setGraphicContext(new GraphicContext());
return g2d;
}

@Test
public void testRotatedGlyph() throws Exception {
runTest("rotated-glyph.svg", new OperatorValidator()
.addOperatorMatch("Tm", "1 0 0 -1 40 110 Tm")
.addOperatorMatch("xshow", "(A)\n[0] xshow")
.addOperatorMatch("Tm", "0.70711 0.70711 0.70711 -0.70711 106.7 110 Tm")
.addOperatorMatch("xshow", "(B)\n[0] xshow")
.addOperatorMatch("Tm", "1 0 0 -1 173.39999 110 Tm")
.addOperatorMatch("xshow", "(C)\n[0] xshow"));
}

}

+ 9
- 0
test/java/org/apache/fop/svg/baseline-shift.svg View File

@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<svg width="150" height="60" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="100%" height="100%" fill="none" stroke="black" stroke-width="2"/>
<g transform="translate(10, 40) scale(20) scale(0.001)">
<text font-family="sans-serif" font-size="1000">
AB<tspan baseline-shift="super">CD</tspan>EF<tspan baseline-shift="sub">GH</tspan>IJ
</text>
</g>
</svg>

+ 8
- 0
test/java/org/apache/fop/svg/dx-dy.svg View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="100%" height="100%" stroke="black" stroke-width="2" fill="none"/>
<g font-family="monospace" font-size="30">
<text x="55" y="35">ABCDE</text>
<text x="55" y="75" dx="0 -4 22 -36 18" dy="0 10 -5 -15 10">ABCDE</text>
</g>
</svg>

+ 193
- 0
test/java/org/apache/fop/svg/font/BasicGlyphVectorTestCase.java View File

@@ -0,0 +1,193 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.awt.Rectangle;
import java.awt.font.GlyphMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.apache.batik.gvt.font.GVTGlyphMetrics;
import org.apache.batik.gvt.font.GVTLineMetrics;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontMetrics;

/**
* Tests all the methods of {@link FOPGVTGlyphVector} with a mocked font.
*/
public class BasicGlyphVectorTestCase extends FOPGVTGlyphVectorTest {

private final int fontSize = 10000;

@Before
public void createGlyphVector() {
FontMetrics metrics = mockFontMetrics();
Font font = mockFont(metrics);
FOPGVTFont gvtFont = mockGVTFont(font);
CharacterIterator it = new StringCharacterIterator("ABC");
glyphVector = new FOPGVTGlyphVector(gvtFont, it, null);
glyphVector.performDefaultLayout();
}

private FontMetrics mockFontMetrics() {
FontMetrics metrics = mock(FontMetrics.class);
when(metrics.getAscender(eq(fontSize))).thenReturn(8000000);
when(metrics.getDescender(eq(fontSize))).thenReturn(-4000000);
when(metrics.getWidth(eq(1), eq(fontSize))).thenReturn(10000000);
when(metrics.getBoundingBox(eq(1), eq(fontSize))).thenReturn(
new Rectangle(-1000000, -2000000, 3000000, 4000000));
when(metrics.getWidth(eq(2), eq(fontSize))).thenReturn(11000000);
when(metrics.getBoundingBox(eq(2), eq(fontSize))).thenReturn(
new Rectangle(-5000000, -6000000, 7000000, 9000000));
when(metrics.getWidth(eq(3), eq(fontSize))).thenReturn(12000000);
when(metrics.getBoundingBox(eq(3), eq(fontSize))).thenReturn(
new Rectangle(-9000000, -10000000, 11000000, 14000000));
return metrics;
}

private Font mockFont(FontMetrics metrics) {
Font font = mock(Font.class);
when(font.getFontMetrics()).thenReturn(metrics);
when(font.getFontSize()).thenReturn(fontSize);
when(font.mapChar(eq('A'))).thenReturn((char) 1);
when(font.mapChar(eq('B'))).thenReturn((char) 2);
when(font.mapChar(eq('C'))).thenReturn((char) 3);
return font;
}

private FOPGVTFont mockGVTFont(Font font) {
FOPGVTFont gvtFont = mock(FOPGVTFont.class);
when(gvtFont.getFont()).thenReturn(font);
when(gvtFont.getLineMetrics(anyInt())).thenReturn(
new GVTLineMetrics(8, 0, null, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0));
return gvtFont;
}

@Test
public void getGlyphCodeReturnsGlyphIndex() {
assertEquals(1, glyphVector.getGlyphCode(0));
assertEquals(2, glyphVector.getGlyphCode(1));
assertEquals(3, glyphVector.getGlyphCode(2));
}

@Test
public void testGetGlyphCodes() {
assertArrayEquals(new int[] {1, 2, 3}, glyphVector.getGlyphCodes(0, 3, null));
assertArrayEquals(new int[] {2, 3}, glyphVector.getGlyphCodes(1, 2, null));
}

@Test
public void testGetGlyphMetrics() {
assertGlyphMetricsEqual(new GVTGlyphMetrics(10, 12, new Rectangle(-1, -2, 3, 4), GlyphMetrics.STANDARD),
glyphVector.getGlyphMetrics(0));
assertGlyphMetricsEqual(new GVTGlyphMetrics(11, 12, new Rectangle(-5, -3, 7, 9), GlyphMetrics.STANDARD),
glyphVector.getGlyphMetrics(1));
assertGlyphMetricsEqual(new GVTGlyphMetrics(12, 12, new Rectangle(-9, -4, 11, 14), GlyphMetrics.STANDARD),
glyphVector.getGlyphMetrics(2));
}

private void assertGlyphMetricsEqual(GVTGlyphMetrics expected, GVTGlyphMetrics actual) {
assertEquals(expected.getHorizontalAdvance(), actual.getHorizontalAdvance(), 0);
assertEquals(expected.getVerticalAdvance(), actual.getVerticalAdvance(), 0);
assertEquals(expected.getBounds2D(), actual.getBounds2D());
assertEquals(expected.getLSB(), actual.getLSB(), 0);
assertEquals(expected.getRSB(), actual.getRSB(), 0);
assertEquals(expected.getType(), actual.getType());
assertEquals(expected.isCombining(), actual.isCombining());
assertEquals(expected.isComponent(), actual.isComponent());
assertEquals(expected.isLigature(), actual.isLigature());
assertEquals(expected.isStandard(), actual.isStandard());
assertEquals(expected.isWhitespace(), actual.isWhitespace());
}

@Test
public void testGetGlyphPosition() {
assertEquals(new Point2D.Float(0, 0), glyphVector.getGlyphPosition(0));
assertEquals(new Point2D.Float(10, 0), glyphVector.getGlyphPosition(1));
assertEquals(new Point2D.Float(21, 0), glyphVector.getGlyphPosition(2));
assertEquals(new Point2D.Float(33, 0), glyphVector.getGlyphPosition(3));
}

@Test
public void testGetGlyphPositions() {
float[] expectedPositions = new float[] {0, 0, 10, 0, 21, 0, 33, 0};
assertArrayEquals(expectedPositions, glyphVector.getGlyphPositions(0, 4, null), 0);
assertArrayEquals(expectedPositions, glyphVector.getGlyphPositions(0, 4, new float[8]), 0);
}

@Test
public void testGetGlyphOutline() {
assertEquals(new Rectangle(-1, -2, 3, 4), glyphVector.getGlyphOutline(0).getBounds());
assertEquals(new Rectangle(5, -3, 7, 9), glyphVector.getGlyphOutline(1).getBounds());
assertEquals(new Rectangle(12, -4, 11, 14), glyphVector.getGlyphOutline(2).getBounds());
}

@Test
public void testGetOutline() {
assertEquals(new Rectangle(-1, -4, 24, 14), glyphVector.getOutline().getBounds());
}

@Test
public void testGetLogicalBounds() {
assertEquals(new Rectangle(0, -8, 33, 12), glyphVector.getLogicalBounds());
}

@Test
public void testGetLogicalBoundsRotated() {
for (int i = 0; i < 3; i++) {
glyphVector.setGlyphTransform(i, new AffineTransform(0.7, 0.7, -0.7, 0.7, 0, 0));
}
assertEquals(new Rectangle2D.Float(-2.8f, -5.6f, 37.8f, 16.8f), glyphVector.getLogicalBounds());
}

@Test
public void testGetBounds() {
assertEquals(new Rectangle(-1, -4, 24, 14), glyphVector.getBounds2D(null));
}

@Test
public void testGetGlyphVisualBounds() {
assertEquals(new Rectangle(-1, -2, 3, 4), glyphVector.getGlyphVisualBounds(0).getBounds());
assertEquals(new Rectangle(5, -3, 7, 9), glyphVector.getGlyphVisualBounds(1).getBounds());
assertEquals(new Rectangle(12, -4, 11, 14), glyphVector.getGlyphVisualBounds(2).getBounds());
}

@Test
public void testGetGlyphLogicalBounds() {
assertEquals(new Rectangle(0, -8, 10, 12), glyphVector.getGlyphLogicalBounds(0).getBounds());
assertEquals(new Rectangle(10, -8, 11, 12), glyphVector.getGlyphLogicalBounds(1).getBounds());
assertEquals(new Rectangle(21, -8, 12, 12), glyphVector.getGlyphLogicalBounds(2).getBounds());
}

}

+ 127
- 0
test/java/org/apache/fop/svg/font/FOPFontFamilyResolverTestCase.java View File

@@ -0,0 +1,127 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collections;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

import org.apache.batik.gvt.font.GVTFontFamily;
import org.apache.batik.gvt.font.GVTLineMetrics;

import org.apache.fop.fonts.FontInfo;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

public class FOPFontFamilyResolverTestCase {

private static FontInfo fontInfo;

private FOPFontFamilyResolver resolver;

@BeforeClass
public static void setUpFontInfo() {
fontInfo = new FontInfoBuilder()
.useDejaVuLGCSerif()
.useDroidSansMono()
.build();
}

@Before
public void createFontFamilyResolver() {
resolver = new FOPFontFamilyResolverImpl(fontInfo);
}

@Test
public void testResolve() {
assertNull(resolver.resolve("Unavailable"));
assertNotNull(resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF));
}

@Test
public void testGetFamilyThatCanDisplay() {
GVTFontFamily family = resolver.getFamilyThatCanDisplay('\u0180');
assertEquals(FontInfoBuilder.DEJAVU_LGC_SERIF, family.getFamilyName());
family = resolver.getFamilyThatCanDisplay('\u02F3');
assertEquals(FontInfoBuilder.DROID_SANS_MONO, family.getFamilyName());
family = resolver.getFamilyThatCanDisplay('\u02DF');
assertNull(family);
}

@Test
public void testDeriveFont() {
FOPGVTFontFamily family = (FOPGVTFontFamily) resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF);
FOPGVTFont font = family.deriveFont(10, Collections.emptyMap());
assertEquals(10, font.getSize(), 0);
assertTrue(font.canDisplay('\u01F6'));
assertFalse(font.canDisplay('\u01F7'));
}

@Test
@Ignore("FOP metrics don't match AWT, but not sure who is right and who is wrong")
public void testLineMetrics() throws FontFormatException, IOException {
FOPGVTFontFamily family = (FOPGVTFontFamily) resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF);
FOPGVTFont font = family.deriveFont(10, Collections.emptyMap());
GVTLineMetrics fopMetrics = font.getLineMetrics("", null);
LineMetrics awtMetrics = getAWTLineMetrics();
printDifference("Ascent", awtMetrics.getAscent(), fopMetrics.getAscent());
printDifference("Descent", awtMetrics.getDescent(), fopMetrics.getDescent());
printDifference("Height", awtMetrics.getHeight(), fopMetrics.getHeight());
printDifference("Leading", awtMetrics.getLeading(), fopMetrics.getLeading());
printDifference("StrikethroughOffset", awtMetrics.getStrikethroughOffset(),
fopMetrics.getStrikethroughOffset());
printDifference("StrikethroughThickness", awtMetrics.getStrikethroughThickness(),
fopMetrics.getStrikethroughThickness());
printDifference("UnderlineOffset", awtMetrics.getUnderlineOffset(),
fopMetrics.getUnderlineOffset());
printDifference("UnderlineThickness", awtMetrics.getUnderlineThickness(),
fopMetrics.getUnderlineThickness());
}

private LineMetrics getAWTLineMetrics() throws FontFormatException, IOException {
File fontFile = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf");
java.awt.Font awtFont = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, fontFile).deriveFont(10f);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
BufferedImage dummyImage = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_RGB);
FontRenderContext frc = ge.createGraphics(dummyImage).getFontRenderContext();
LineMetrics awtMetrics = awtFont.getLineMetrics("ABC", frc);
return awtMetrics;
}

private void printDifference(String value, float awt, float fop) {
System.out.println(String.format("%22s AWT: %10f FOP: %10f Difference: %.2f%%", value, awt, fop,
(fop - awt) / awt * 100));
}

}

+ 72
- 0
test/java/org/apache/fop/svg/font/FOPGVTFontTestCase.java View File

@@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.text.StringCharacterIterator;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.apache.fop.fonts.Font;
import org.apache.fop.svg.font.FOPGVTFont;

public class FOPGVTFontTestCase {

private FOPGVTFont font;

@Before
public void createFont() {
Font f = mock(Font.class);
when(f.hasChar(eq((char) 0))).thenReturn(false);
when(f.hasChar(eq((char) 1))).thenReturn(true);
font = new FOPGVTFont(f, null);
}

@Test
public void testCanDisplayUpTo() {
char[] text = new char[] {1, 1, 1};
testCanDisplayUpToVariants(text, -1, 0, 3);
testCanDisplayUpToVariants(text, -1, 1, 3);
text = new char[] {1, 1, 0, 1};
testCanDisplayUpToVariants(text, 2, 0, 4);
testCanDisplayUpToVariants(text, 2, 1, 4);
testCanDisplayUpToVariants(text, 2, 2, 4);
testCanDisplayUpToVariants(text, -1, 3, 4);
testCanDisplayUpToVariants(text, -1, 1, 2);
}

@Test
public void testCanDisplayUpToString() {
assertEquals(-1, font.canDisplayUpTo(new String(new char[] {1, 1, 1})));
assertEquals(0, font.canDisplayUpTo(new String(new char[] {0, 1, 1})));
assertEquals(1, font.canDisplayUpTo(new String(new char[] {1, 0, 1})));
assertEquals(2, font.canDisplayUpTo(new String(new char[] {1, 1, 0})));
}

private void testCanDisplayUpToVariants(char[] text, int expected, int start, int limit) {
assertEquals(expected, font.canDisplayUpTo(text, start, limit));
assertEquals(expected, font.canDisplayUpTo(new StringCharacterIterator(new String(text)), start, limit));
}
}

+ 27
- 0
test/java/org/apache/fop/svg/font/FOPGVTGlyphVectorTest.java View File

@@ -0,0 +1,27 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;


public abstract class FOPGVTGlyphVectorTest {

protected FOPGVTGlyphVector glyphVector;

}

+ 102
- 0
test/java/org/apache/fop/svg/font/FontInfoBuilder.java View File

@@ -0,0 +1,102 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.EncodingMode;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontMetrics;
import org.apache.fop.fonts.truetype.TTFFontLoader;

class FontInfoBuilder {

public static final String DEJAVU_LGC_SERIF = "DejaVu LGC Serif";

public static final String DROID_SANS_MONO = "Droid Sans Mono";

private static final boolean USE_ADVANCED_BY_DEFAULT = true;

private FontInfo fontInfo;

private int fontKey;

public FontInfoBuilder() {
reset();
}

private void reset() {
fontInfo = new FontInfo();
fontKey = 1;
}

public FontInfoBuilder useDejaVuLGCSerif() {
return useDejaVuLGCSerif(USE_ADVANCED_BY_DEFAULT);
}

public FontInfoBuilder useDejaVuLGCSerif(boolean useAdvanced) {
try {
return useFont(DEJAVU_LGC_SERIF, "DejaVuLGCSerif.ttf", useAdvanced);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public FontInfoBuilder useDroidSansMono() {
return useDroidSansMono(USE_ADVANCED_BY_DEFAULT);
}

public FontInfoBuilder useDroidSansMono(boolean useAdvanced) {
try {
return useFont(DROID_SANS_MONO, "DroidSansMono.ttf", useAdvanced);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private FontInfoBuilder useFont(String fontName, String filename, boolean useAdvanced)
throws IOException, URISyntaxException {
URI baseURI = new File("test/resources/fonts/ttf").toURI();
InternalResourceResolver resolver = ResourceResolverFactory.createDefaultInternalResourceResolver(baseURI);
TTFFontLoader fontLoader = new TTFFontLoader(new URI(filename), null, true,
EmbeddingMode.AUTO, EncodingMode.AUTO, true, useAdvanced, resolver);
FontMetrics font = fontLoader.getFont();
registerFont(font, "F" + fontKey++, fontName);
return this;
}

private void registerFont(FontMetrics font, String key, String familyName) {
fontInfo.addMetrics(key, font);
fontInfo.addFontProperties(key, familyName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
}

public FontInfo build() {
FontInfo fontInfo = this.fontInfo;
reset();
return fontInfo;
}
}

+ 91
- 0
test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java View File

@@ -0,0 +1,91 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.svg.font;

import java.util.Collections;

import org.junit.Test;

import org.apache.fop.fonts.FontInfo;

import static org.junit.Assert.assertEquals;

/**
* Specifically tests glyph positioning from a real font.
*/
public class GlyphLayoutTestCase extends FOPGVTGlyphVectorTest {

/**
* Glyph positioning using the legacy kern table.
*/
@Test
public void testBasicGlyphPositioning() throws Exception {
testGlyphLayout(false);
}

/**
* Glyph positioning using GPOS sub-tables.
*/
@Test
public void testAdvancedGlyphPositioning() throws Exception {
testGlyphLayout(true);
}

private void testGlyphLayout(boolean useAdvanced) {
FOPGVTFont font = loadFont(useAdvanced);
glyphVector = (FOPGVTGlyphVector) font.createGlyphVector(null, "L\u201DP,V.F,A\u2019LT.");
glyphVector.performDefaultLayout();
// Values in font units (unitsPerEm = 2048), glyph width - kern
int[] widths = {
/* L */ 1360 - 491,
/* " */ 1047,
/* P */ 1378 - 415,
/* , */ 651,
/* V */ 1479 - 358,
/* . */ 651,
/* F */ 1421 - 319,
/* , */ 651,
/* A */ 1479 - 301,
/* ' */ 651,
/* L */ 1360 - 167,
/* T */ 1366 - 301,
/* . */ 651};
checkGlyphPositions(13, widths);
}

private FOPGVTFont loadFont(boolean useAdvanced) {
FontInfo fontInfo = new FontInfoBuilder().useDejaVuLGCSerif(useAdvanced).build();
FOPFontFamilyResolver resolver = new FOPFontFamilyResolverImpl(fontInfo);
FOPGVTFontFamily family = resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF);
return family.deriveFont(1000, Collections.emptyMap());
}

private void checkGlyphPositions(int expectedGlyphCount, int[] widths) {
assertEquals(expectedGlyphCount, glyphVector.getNumGlyphs());
float[] positions = new float[2 * (widths.length + 1)];
for (int i = 0, n = 2; i < widths.length; i++, n += 2) {
positions[n] = positions[n - 2] + widths[i] / 2.048f;
}
for (int i = 0; i <= widths.length; i++) {
assertEquals(positions[2 * i], glyphVector.getGlyphPosition(i).getX(), 3);
}
}

}

+ 0
- 0
test/java/org/apache/fop/svg/glyph-orientation.svg View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save