Browse Source

Brought the branch in sync with rev. 1562429 of trunk


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_FopFontsForSVG@1562866 13f79535-47bb-0310-9956-ffa450edef68
pull/22/head
Vincent Hennebert 10 years ago
parent
commit
563da808e4
100 changed files with 6667 additions and 3055 deletions
  1. 8
    9
      build.xml
  2. 11
    5
      checkstyle-5.5.xml
  3. 8
    4
      checkstyle-suppressions.xml
  4. 8
    8
      examples/fo/basic/leader.fo
  5. 223
    46
      findbugs-exclude.xml
  6. BIN
      lib/fontbox-1.8.3-patched.jar
  7. 395
    0
      lib/pdfbox-1645.patch
  8. 738
    0
      lib/pdfbox-1646.patch
  9. BIN
      lib/xmlgraphics-commons-svn-trunk.jar
  10. 6
    7
      src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/GenerateBidiClass.java
  11. 22
    26
      src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/GenerateBidiTestData.java
  12. 1
    0
      src/documentation/intermediate-format-ng/fop-intermediate-format-ng-content.xsd
  13. 1
    0
      src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory
  14. 3
    2
      src/java/org/apache/fop/Version.java
  15. 1
    1
      src/java/org/apache/fop/apps/FOUserAgent.java
  16. 36
    17
      src/java/org/apache/fop/apps/FopConfParser.java
  17. 18
    1
      src/java/org/apache/fop/area/AreaTreeParser.java
  18. 1
    1
      src/java/org/apache/fop/area/Footnote.java
  19. 4
    1
      src/java/org/apache/fop/area/Trait.java
  20. 7
    8
      src/java/org/apache/fop/area/inline/Container.java
  21. 4
    40
      src/java/org/apache/fop/cli/CommandLineOptions.java
  22. 0
    1
      src/java/org/apache/fop/complexscripts/bidi/BidiClass.java
  23. 3
    7
      src/java/org/apache/fop/complexscripts/bidi/BidiResolver.java
  24. 1
    4
      src/java/org/apache/fop/complexscripts/bidi/DelimitedTextRange.java
  25. 2
    9
      src/java/org/apache/fop/complexscripts/bidi/InlineRun.java
  26. 1
    4
      src/java/org/apache/fop/complexscripts/bidi/TextInterval.java
  27. 12
    17
      src/java/org/apache/fop/complexscripts/bidi/UnflattenProcessor.java
  28. 28
    41
      src/java/org/apache/fop/complexscripts/bidi/UnicodeBidiAlgorithm.java
  29. 5
    6
      src/java/org/apache/fop/complexscripts/fonts/GlyphClassTable.java
  30. 3
    5
      src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageTable.java
  31. 0
    1
      src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionSubtable.java
  32. 0
    1
      src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionTable.java
  33. 1
    3
      src/java/org/apache/fop/complexscripts/fonts/GlyphMappingTable.java
  34. 0
    1
      src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java
  35. 3
    5
      src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java
  36. 52
    55
      src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java
  37. 10
    11
      src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java
  38. 1
    2
      src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionState.java
  39. 3
    4
      src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionSubtable.java
  40. 14
    16
      src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionTable.java
  41. 0
    1
      src/java/org/apache/fop/complexscripts/fonts/GlyphSubtable.java
  42. 21
    28
      src/java/org/apache/fop/complexscripts/fonts/GlyphTable.java
  43. 45
    48
      src/java/org/apache/fop/complexscripts/fonts/OTFAdvancedTypographicTableReader.java
  44. 9
    13
      src/java/org/apache/fop/complexscripts/scripts/ArabicScriptProcessor.java
  45. 11
    16
      src/java/org/apache/fop/complexscripts/scripts/DevanagariScriptProcessor.java
  46. 11
    16
      src/java/org/apache/fop/complexscripts/scripts/GujaratiScriptProcessor.java
  47. 11
    16
      src/java/org/apache/fop/complexscripts/scripts/GurmukhiScriptProcessor.java
  48. 4
    13
      src/java/org/apache/fop/complexscripts/scripts/IndicScriptProcessor.java
  49. 3
    9
      src/java/org/apache/fop/complexscripts/scripts/ScriptProcessor.java
  50. 17
    23
      src/java/org/apache/fop/complexscripts/util/CharScript.java
  51. 8
    11
      src/java/org/apache/fop/complexscripts/util/GlyphSequence.java
  52. 15
    24
      src/java/org/apache/fop/complexscripts/util/NumberConverter.java
  53. 0
    1
      src/java/org/apache/fop/complexscripts/util/UTF32.java
  54. 4
    1
      src/java/org/apache/fop/fo/Constants.java
  55. 7
    0
      src/java/org/apache/fop/fo/FOPropertyMapping.java
  56. 30
    3
      src/java/org/apache/fop/fo/FObj.java
  57. 2
    1
      src/java/org/apache/fop/fo/expr/FunctionBase.java
  58. 2
    1
      src/java/org/apache/fop/fo/expr/PropertyParser.java
  59. 2
    0
      src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
  60. 16
    2
      src/java/org/apache/fop/fo/flow/BlockContainer.java
  61. 77
    95
      src/java/org/apache/fop/fo/flow/InlineContainer.java
  62. 12
    1
      src/java/org/apache/fop/fo/flow/table/Table.java
  63. 17
    1
      src/java/org/apache/fop/fo/pagination/PageSequence.java
  64. 5
    1
      src/java/org/apache/fop/fo/properties/GenericShorthandParser.java
  65. 2
    2
      src/java/org/apache/fop/fonts/FontLoader.java
  66. 10
    6
      src/java/org/apache/fop/fonts/FontManagerConfigurator.java
  67. 2
    1
      src/java/org/apache/fop/fonts/FontTriplet.java
  68. 52
    17
      src/java/org/apache/fop/fonts/MultiByteFont.java
  69. 1
    1
      src/java/org/apache/fop/fonts/SingleByteFont.java
  70. 0
    6
      src/java/org/apache/fop/fonts/apps/AbstractFontReader.java
  71. 0
    11
      src/java/org/apache/fop/fonts/apps/PFMReader.java
  72. 3
    13
      src/java/org/apache/fop/fonts/apps/TTFReader.java
  73. 2
    2
      src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
  74. 927
    0
      src/java/org/apache/fop/fonts/cff/CFFDataReader.java
  75. 2
    2
      src/java/org/apache/fop/fonts/truetype/GlyfTable.java
  76. 3
    3
      src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java
  77. 73
    63
      src/java/org/apache/fop/fonts/truetype/OFFontLoader.java
  78. 1
    1
      src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java
  79. 41
    35
      src/java/org/apache/fop/fonts/truetype/OFTableName.java
  80. 109
    0
      src/java/org/apache/fop/fonts/truetype/OTFFile.java
  81. 1097
    0
      src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
  82. 1971
    0
      src/java/org/apache/fop/fonts/truetype/OpenFont.java
  83. 74
    1971
      src/java/org/apache/fop/fonts/truetype/TTFFile.java
  84. 53
    53
      src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
  85. 1
    1
      src/java/org/apache/fop/fonts/type1/AFMFile.java
  86. 6
    3
      src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java
  87. 20
    5
      src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
  88. 0
    3
      src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java
  89. 28
    0
      src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
  90. 12
    12
      src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
  91. 10
    54
      src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
  92. 10
    55
      src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
  93. 3
    0
      src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
  94. 8
    2
      src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
  95. 1
    0
      src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
  96. 19
    0
      src/java/org/apache/fop/layoutmgr/LayoutManager.java
  97. 5
    7
      src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
  98. 46
    32
      src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
  99. 112
    0
      src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java
  100. 0
    0
      src/java/org/apache/fop/layoutmgr/TraitSetter.java

+ 8
- 9
build.xml View File

@@ -563,16 +563,17 @@ list of possible build targets.
<include name="org/apache/fop/apps/Fop.class"/>
<include name="org/apache/fop/apps/FOPException.class"/>
<include name="org/apache/fop/apps/io/**"/>
<include name="org/apache/fop/area/AreaTreeControl*"/>
<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/image/loader/batik/BatikImageFlavors*.class"/>
<include name="org/apache/fop/svg/**"/>
<include name="org/apache/fop/fonts/**"/>
<include name="org/apache/fop/render/shading/**"/>
<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"/>
<include name="org/apache/fop/util/ASCII*.class"/>
@@ -1046,10 +1047,8 @@ NOTE:
<!-- Checkstyle -->
<!-- =================================================================== -->
<property name="checkstyle.location" value="${lib-tools}/checkstyle-5.5-all.jar" />
<property name="checkstyle.noframes.xslt" value="${basedir}/checkstyle-noframes.xsl" />
<property name="checkstyle.config" value="${basedir}/checkstyle-5.5.xml" />
<path id="checkstyle-classpath">
<path refid="libs-build-classpath"/>
<pathelement location="${checkstyle.location}"/>
</path>
<condition property="checkstyle.avail">
@@ -1057,20 +1056,18 @@ NOTE:
<available classname="com.puppycrawl.tools.checkstyle.CheckStyleTask">
<classpath refid="checkstyle-classpath"/>
</available>
<available file="${checkstyle.noframes.xslt}"/>
<available file="${checkstyle.config}"/>
</and>
</condition>
<target name="checkstyle-avail" unless="checkstyle.avail">
<echo message="Checkstyle support NOT present. Please download it from http://checkstyle.sf.net/ and"/>
<echo message="... please provide ${checkstyle.location}"/>
<echo message="... please provide ${checkstyle.noframes.xslt}"/>
<echo message="... please provide ${checkstyle.config}"/>
</target>
<target name="checkstyle" depends="package, checkstyle-avail" if="checkstyle.avail" description="Runs Checkstyle for a code quality report">
<taskdef name="checkstyle" classname="com.puppycrawl.tools.checkstyle.CheckStyleTask" classpathref="checkstyle-classpath"/>
<mkdir dir="${build.dir}"/>
<checkstyle config="${checkstyle.config}" failonviolation="false">
<checkstyle config="${checkstyle.config}" failonviolation="true" maxWarnings="0">
<classpath>
<path refid="checkstyle-classpath"/>
<pathelement location="${build.classes.dir}"/>
@@ -1078,9 +1075,10 @@ NOTE:
<pathelement location="${build.codegen-classes.dir}"/>
</classpath>
<fileset dir="${src.dir}" includes="**/*.java"/>
<fileset dir="${test.dir}" includes="**/*.java"/>
<formatter type="xml" toFile="${build.dir}/report_checkstyle.xml"/>
<formatter type="plain"/>
</checkstyle>
<xslt in="${build.dir}/report_checkstyle.xml" out="${build.dir}/report_checkstyle.html" style="${checkstyle.noframes.xslt}"/>
</target>
<!-- =================================================================== -->
<!-- PMD -->
@@ -1092,6 +1090,7 @@ NOTE:
<path refid="libs-tools-build-classpath"/>
</classpath>
</taskdef>
<mkdir dir="${build.dir}"/>
<pmd shortFilenames="true" targetjdk="${javac.target}">
<ruleset>basic</ruleset>
<ruleset>rulesets/migrating_to_14.xml</ruleset>
@@ -1510,7 +1509,7 @@ NOTE:
<!-- Special target for Gump -->
<!-- =================================================================== -->
<target name="gump" depends="package,transcoder-pkg"/>
<target name="gump-test" depends="junit-all">
<target name="gump-test" depends="junit-all,checkstyle">
<fail>
<condition>
<or>

+ 11
- 5
checkstyle-5.5.xml View File

@@ -37,15 +37,25 @@

<!-- ===================================================================================================== -->
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CSOFF\: ([\w\|]+)"/>
<property name="offCommentFormat" value="CSOFF\: (LineLength)"/>
<property name="onCommentFormat" value="CSON\: ([\w\|]+)"/>
<property name="checkFormat" value="$1"/>
</module>
<!-- ===================================================================================================== -->

<module name="SuppressionFilter">
<property name="file" value="${samedir}/checkstyle-suppressions.xml"/>
</module>

<!-- ===================================================================================================== -->
<module name="TreeWalker">

<!-- ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... -->
<module name="LineLength">
<property name="max" value="120"/>
</module>
<!-- ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... -->

<!-- ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... -->
<module name="AnnotationUseStyle"/>
<!-- ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... -->
@@ -172,10 +182,6 @@
<property name="allowLineBreaks" value="false"/>
<property name="tokens" value="BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
</module>
<module name="NoWhitespaceAfter">
<property name="allowLineBreaks" value="true"/>
<property name="tokens" value="ARRAY_INIT"/>
</module>
<!-- ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... -->

<!-- ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... -->

+ 8
- 4
checkstyle-suppressions.xml View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN" "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress files="org/apache/fop/fo/FOPropertyMapping.java" checks="FileLengthCheck"/>
<suppress files="org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java" checks="FileLengthCheck"/>
<suppress files="org/apache/fop/complexscripts/fonts/OTFAdvancedTypographicTableReader.java" checks="FileLengthCheck"/>
<suppress files="org/apache/fop/Version.java" lines="40-50" checks="LineLengthCheck"/>
<suppress files="org/apache/fop/afp/fonts/CharactersetEncoder.java" checks="FinalClass"/>
<suppress files="org/apache/fop/complexscripts/bidi/BidiClass.java" checks="WhitespaceAfter"/>
<suppress files="org/apache/fop/complexscripts/bidi/GenerateBidiTestData.java" checks="SimplifyBooleanReturn"/>
<suppress files="org/apache/fop/complexscripts/scripts/ArabicScriptProcessor.java" checks="SimplifyBooleanReturn"/>
<suppress files="org/apache/fop/complexscripts/util/CharScript.java" checks="SimplifyBooleanReturn"/>
<suppress files="org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java" checks="AvoidNestedBlocks"/>
<suppress files="org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java" checks="AvoidNestedBlocks"/>
<suppress files="org/apache/fop/fo/flow/MarkersTestCase.java" checks="LocalVariableName"/>
</suppressions>

+ 8
- 8
examples/fo/basic/leader.fo View File

@@ -2,7 +2,7 @@

<!-- examples for the use of the fo leader -->

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="sans-serif">

<fo:layout-master-set>

@@ -272,7 +272,7 @@
<fo:list-item>
<!-- insert a bullet -->
<fo:list-item-label end-indent="label-end()">
<fo:block><fo:inline font-size="10pt" font-family="Symbol">&#183;</fo:inline></fo:block>
<fo:block><fo:inline font-size="10pt">&#183;</fo:inline></fo:block>
</fo:list-item-label>
<!-- list text -->
<fo:list-item-body start-indent="body-start()">
@@ -291,7 +291,7 @@
<fo:list-item>
<!-- insert a bullet -->
<fo:list-item-label end-indent="label-end()">
<fo:block><fo:inline font-size="10pt" font-family="Symbol">&#183;</fo:inline></fo:block>
<fo:block><fo:inline font-size="10pt">&#183;</fo:inline></fo:block>
</fo:list-item-label>
<!-- list text -->
<fo:list-item-body start-indent="body-start()">
@@ -391,7 +391,7 @@

<fo:table-row line-height="12pt">
<fo:table-cell><fo:block text-align="end">A) </fo:block></fo:table-cell>
<fo:table-cell><fo:block text-align="start">This is some longer sample text<fo:leader leader-pattern="dots"
<fo:table-cell><fo:block text-align="start" text-align-last="justify">This is some longer sample text<fo:leader leader-pattern="dots"
leader-pattern-width="8pt"
leader-alignment="reference-area"
/></fo:block></fo:table-cell>
@@ -401,7 +401,7 @@

<fo:table-row line-height="12pt">
<fo:table-cell><fo:block text-align="end">B) </fo:block></fo:table-cell>
<fo:table-cell><fo:block text-align="start">Some text<fo:leader leader-pattern="dots"
<fo:table-cell><fo:block text-align="start" text-align-last="justify">Some text<fo:leader leader-pattern="dots"
leader-pattern-width="8pt"
leader-alignment="reference-area"
/></fo:block></fo:table-cell>
@@ -410,7 +410,7 @@

<fo:table-row line-height="12pt">
<fo:table-cell><fo:block text-align="end" >C) </fo:block></fo:table-cell>
<fo:table-cell><fo:block text-align="start">Text<fo:leader leader-pattern="dots"
<fo:table-cell><fo:block text-align="start" text-align-last="justify">Text<fo:leader leader-pattern="dots"
leader-pattern-width="8pt"
leader-alignment="reference-area"
/></fo:block></fo:table-cell>
@@ -419,7 +419,7 @@

<fo:table-row line-height="12pt">
<fo:table-cell><fo:block text-align="end">D) </fo:block></fo:table-cell>
<fo:table-cell><fo:block text-align="start">This text is even longer than the first entry <fo:leader leader-pattern="dots"
<fo:table-cell><fo:block text-align="start" text-align-last="justify">This text is even longer than the first entry <fo:leader leader-pattern="dots"
leader-pattern-width="8pt"
leader-alignment="reference-area"
/></fo:block></fo:table-cell>
@@ -428,7 +428,7 @@

<fo:table-row line-height="12pt">
<fo:table-cell><fo:block text-align="end">E) </fo:block></fo:table-cell>
<fo:table-cell><fo:block text-align="start">Shorter text example<fo:leader leader-pattern="dots"
<fo:table-cell><fo:block text-align="start" text-align-last="justify">Shorter text example<fo:leader leader-pattern="dots"
leader-pattern-width="8pt"
leader-alignment="reference-area"
/></fo:block></fo:table-cell>

+ 223
- 46
findbugs-exclude.xml View File

@@ -1,37 +1,7 @@
<?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"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont$1"/>
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON"/>
</Match>
<Match>
@@ -438,6 +408,11 @@
<Method name="buildCIDSet"/>
<Bug pattern="OS_OPEN_STREAM"/>
</Match>
<Match>
<Class name="org.apache.fop.pdf.PDFFactory"/>
<Method name="makeFont"/>
<Bug pattern="BC_UNCONFIRMED_CAST_OF_RETURN_VALUE"/>
</Match>
<Match>
<Class name="org.apache.fop.pdf.PDFOutputIntent"/>
<Method name="toPDF"/>
@@ -864,7 +839,7 @@
<Bug pattern="BIT_IOR_OF_SIGNED_BYTE"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFDirTabEntry"/>
<Class name="org.apache.fop.fonts.truetype.OFDirTabEntry"/>
<Method name="toString"/>
<Bug pattern="DMI_INVOKING_TOSTRING_ON_ARRAY"/>
</Match>
@@ -1019,7 +994,7 @@
<Bug pattern="UWF_UNWRITTEN_FIELD"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFDirTabEntry"/>
<Class name="org.apache.fop.fonts.truetype.OFDirTabEntry"/>
<Field name="checksum"/>
<Bug pattern="UWF_UNWRITTEN_FIELD"/>
</Match>
@@ -2173,37 +2148,37 @@
<Bug pattern="DM_NUMBER_CTOR"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="glyphToUnicode"/>
<Bug pattern="DM_NUMBER_CTOR"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="initAnsiWidths"/>
<Bug pattern="DM_NUMBER_CTOR"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="readKerning"/>
<Bug pattern="DM_NUMBER_CTOR"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="readUnicodeCmap"/>
<Bug pattern="DM_NUMBER_CTOR"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="unicodeToGlyph"/>
<Bug pattern="DM_NUMBER_CTOR"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="unicodeToWinAnsi"/>
<Bug pattern="DM_NUMBER_CTOR"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile$UnicodeMapping"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont$UnicodeMapping"/>
<Method name="&lt;init&gt;"/>
<Bug pattern="DM_NUMBER_CTOR"/>
</Match>
@@ -2653,7 +2628,7 @@
<Bug pattern="ITA_INEFFICIENT_TO_ARRAY"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="unicodeToWinAnsi"/>
<Bug pattern="ITA_INEFFICIENT_TO_ARRAY"/>
</Match>
@@ -2882,7 +2857,7 @@
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile$UnicodeMapping"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont$UnicodeMapping"/>
<!--Neither method nor field-->
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC_NEEDS_THIS"/>
</Match>
@@ -2932,7 +2907,7 @@
<Bug pattern="UPM_UNCALLED_PRIVATE_METHOD"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="printMaxMin"/>
<Bug pattern="UPM_UNCALLED_PRIVATE_METHOD"/>
</Match>
@@ -3112,7 +3087,7 @@
<Bug pattern="WMI_WRONG_MAP_ITERATOR"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="readKerning"/>
<Bug pattern="WMI_WRONG_MAP_ITERATOR"/>
</Match>
@@ -3777,7 +3752,7 @@
<Bug pattern="DLS_DEAD_LOCAL_STORE"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFFile"/>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Method name="readFont"/>
<Bug pattern="DLS_DEAD_LOCAL_STORE"/>
</Match>
@@ -5051,7 +5026,7 @@
<Bug pattern="EI_EXPOSE_REP"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.TTFDirTabEntry"/>
<Class name="org.apache.fop.fonts.truetype.OFDirTabEntry"/>
<Method name="getTag"/>
<Bug pattern="EI_EXPOSE_REP"/>
</Match>
@@ -5256,4 +5231,206 @@
</Or>
<Bug pattern="BC_UNCONFIRMED_CAST"/>
</Match>
<Match>
<Or>
<Class name="org.apache.fop.fo.properties.CommonAural"/>
<Class name="org.apache.fop.fo.properties.CommonMarginInline"/>
<Class name="org.apache.fop.render.pdf.PDFSVGHandler$PDFInfo"/>
<Class name="org.apache.fop.fo.properties.CommonRelativePosition"/>
</Or>
<Or>
<Bug pattern="UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD"/>
<Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"/>
</Or>
</Match>
<Match>
<Or>
<Class name="org.apache.fop.forms.FormLayoutManagerMakerProvider$CheckBoxLayoutManagerMaker"/>
<Class name="org.apache.fop.forms.FormLayoutManagerMakerProvider$ComboBoxLayoutManagerMaker"/>
<Class name="org.apache.fop.forms.FormLayoutManagerMakerProvider$InputLayoutManagerMaker"/>
<Class name="org.apache.fop.forms.FormLayoutManagerMakerProvider$MultilineInputLayoutManagerMaker"/>
<Class name="org.apache.fop.forms.FormLayoutManagerMakerProvider$RadioButtonLayoutManagerMaker"/>
<Class name="org.apache.fop.forms.FormLayoutManagerMakerProvider$TriggerLayoutManagerMaker"/>
<Class name="org.apache.fop.render.intermediate.IFRenderer$1"/>
<Class name="org.apache.fop.render.intermediate.IFRenderer$3"/>
<Class name="org.apache.fop.render.intermediate.IFRenderer$4"/>
<Class name="org.apache.fop.render.intermediate.IFRenderer$5"/>
<Class name="org.apache.fop.render.intermediate.IFRenderer$6"/>
<Class name="org.apache.fop.render.pdf.PDFPainter$InputPainter"/>
<Class name="org.apache.fop.render.pdf.PDFPainter$MultilineInputPainter"/>
<Class name="org.apache.fop.render.pdf.PDFPainter$RadioButtonPainter"/>
<Class name="org.apache.fop.render.pdf.PDFPainter$TriggerPainter"/>
<Class name="org.apache.fop.render.pdf.PDFPainter$ComboBoxPainter"/>
<Class name="org.apache.fop.render.pdf.PDFPainter$CheckboxPainter"/>
</Or>
<Or>
<Bug pattern="BC_UNCONFIRMED_CAST"/>
<Bug pattern="BC_UNCONFIRMED_CAST_OF_RETURN_VALUE"/>
</Or>
</Match>
<Match>
<Or>
<Class name="org.apache.fop.fo.flow.Float"/>
<Class name="org.apache.fop.fo.flow.MultiCase"/>
<Class name="org.apache.fop.fo.flow.MultiProperties"/>
<Class name="org.apache.fop.fo.flow.MultiPropertySet"/>
<Class name="org.apache.fop.fo.flow.MultiSwitch"/>
<Class name="org.apache.fop.fo.flow.MultiToggle"/>
<Class name="org.apache.fop.fo.flow.table.TableAndCaption"/>
<Class name="org.apache.fop.fo.flow.table.TableCaption"/>
<Class name="org.apache.fop.fonts.apps.AbstractFontReader"/>
<Class name="org.apache.fop.render.rtf.rtflib.rtfdoc.RtfElement"/>
</Or>
<Bug pattern="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD"/>
</Match>
<Match>
<Or>
<Class name="org.apache.fop.pdf.PDFFunction"/>
<Class name="org.apache.fop.pdf.PDFGoTo"/>
<Class name="org.apache.fop.pdf.PDFLink"/>
<Class name="org.apache.fop.pdf.PDFPattern"/>
<Class name="org.apache.fop.svg.ACIUtils"/>
<Class name="org.apache.fop.svg.PDFTextPainter"/>
</Or>
<Bug pattern="FE_FLOATING_POINT_EQUALITY"/>
</Match>
<Match>
<Or>
<Class name="org.apache.fop.area.BodyRegion"/>
<Class name="org.apache.fop.area.Page"/>
<Class name="org.apache.fop.area.PageViewport"/>
<Class name="org.apache.fop.area.RegionReference"/>
<Class name="org.apache.fop.area.RegionViewport"/>
<Class name="org.apache.fop.hyphenation.CharVector"/>
<Class name="org.apache.fop.hyphenation.TernaryTree"/>
<Class name="org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes"/>
</Or>
<Bug pattern="CN_IDIOM_NO_SUPER_CALL"/>
</Match>
<Match>
<Or>
<Class name="org.apache.fop.forms.CheckBoxArea"/>
<Class name="org.apache.fop.forms.ComboBox"/>
<Class name="org.apache.fop.forms.RadioButtonArea"/>
</Or>
<Bug pattern="SE_TRANSIENT_FIELD_NOT_RESTORED"/>
</Match>
<Match>
<Or>
<Class name="org.apache.fop.layoutmgr.PageBreaker"/>
<Class name="org.apache.fop.layoutmgr.BlockContainerLayoutManager"/>
</Or>
<Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE"/>
</Match>
<Match>
<Class name="org.apache.fop.layoutmgr.BlockContainerLayoutManager"/>
<Bug pattern="NP_LOAD_OF_KNOWN_NULL_VALUE"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.OpenFont"/>
<Bug pattern="DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS"/>
</Match>
<Match>
<Class name="org.apache.fop.apps.io.ResourceResolverFactory$FileDeletingInputStream"/>
<Bug pattern="RV_RETURN_VALUE_IGNORED_BAD_PRACTICE"/>
</Match>
<Match>
<Class name="org.apache.fop.fo.properties.FontFamilyProperty"/>
<Bug pattern="EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC"/>
</Match>
<Match>
<Class name="org.apache.fop.render.ps.PSImageObject"/>
<Or>
<Bug pattern="EI_EXPOSE_REP"/>
<Bug pattern="EI_EXPOSE_REP2"/>
</Or>
</Match>
<Match>
<Class name="org.apache.fop.fonts.cff.CFFDataReader"/>
<Bug pattern="DM_DEFAULT_ENCODING"/>
</Match>
<Match>
<Class name="org.apache.fop.fonts.cff.CFFDataReader$CFFIndexData"/>
<Or>
<Bug pattern="SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH"/>
<Bug pattern="SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH_TO_THROW"/>
</Or>
</Match>
<Match>
<Class name="org.apache.fop.fonts.cff.CFFDataReader$CFFSubTable"/>
<Or>
<Bug pattern="EI_EXPOSE_REP"/>
<Bug pattern="EI_EXPOSE_REP2"/>
</Or>
</Match>
<Match>
<Class name="org.apache.fop.fonts.cff.CFFDataReader$DICTEntry"/>
<Or>
<Bug pattern="EI_EXPOSE_REP"/>
<Bug pattern="EI_EXPOSE_REP2"/>
</Or>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.OTFFile"/>
<Or>
<Bug pattern="ITA_INEFFICIENT_TO_ARRAY"/>
<Bug pattern="DM_DEFAULT_ENCODING"/>
</Or>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.OTFSubSetFile"/>
<Or>
<Bug pattern="ITA_INEFFICIENT_TO_ARRAY"/>
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC"/>
<Bug pattern="UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR"/>
<Bug pattern="DM_DEFAULT_ENCODING"/>
</Or>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.OTFSubSetFile$1"/>
<Or>
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC"/>
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON"/>
</Or>
</Match>
<Match>
<Class name="org.apache.fop.fonts.truetype.OTFSubSetFile$FDIndexReference"/>
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC"/>
</Match>
<Match>
<Class name="org.apache.fop.render.ps.PSFontUtils"/>
<Bug pattern="DM_DEFAULT_ENCODING"/>
</Match>
<Match>
<Class name="org.apache.fop.forms.IField$Field"/>
<Bug pattern="SE_TRANSIENT_FIELD_NOT_RESTORED"/>
</Match>
<Match>
<Or>
<Class name="org.apache.fop.forms.IField$Field"/>
<Class name="org.apache.fop.forms.TriggerArea"/>
<Class name="org.apache.fop.forms.traits.AdditionalActionTrait"/>
</Or>
<Bug pattern="SE_TRANSIENT_FIELD_NOT_RESTORED"/>
</Match>
<Match>
<Class name="org.apache.fop.render.pdf.extensions.PDFExtensionHandlerFactory"/>
<Method name="getSupportedNamespaces"/>
<Bug pattern="EI_EXPOSE_REP"/>
</Match>
<Match>
<Class name="org.apache.fop.render.pdf.extensions.PDFDictionaryEntryExtension"/>
<Method name="getValueAsNumber"/>
<Bug pattern="FE_FLOATING_POINT_EQUALITY"/>
</Match>
<Match>
<Class name="org.apache.fop.render.pdf.extensions.PDFDictionaryType"/>
<Method name="hasValueOfElementName"/>
<Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE"/>
</Match>
<Match>
<Class name="org.apache.fop.render.pdf.extensions.PDFDictionaryEntryType"/>
<Method name="hasValueOfElementName"/>
<Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE"/>
</Match>
</FindBugsFilter>

BIN
lib/fontbox-1.8.3-patched.jar View File


+ 395
- 0
lib/pdfbox-1645.patch View File

@@ -0,0 +1,395 @@
Index: fontbox/src/test/java/org/apache/fontbox/cff/CharStringRendererTest.java
===================================================================
--- fontbox/src/test/java/org/apache/fontbox/cff/CharStringRendererTest.java (revision 0)
+++ fontbox/src/test/java/org/apache/fontbox/cff/CharStringRendererTest.java (revision 0)
@@ -0,0 +1,28 @@
+package org.apache.fontbox.cff;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class CharStringRendererTest {
+
+ @Test
+ public void testArgumentValidation() {
+ CharStringRenderer renderer = new CharStringRenderer();
+ List<Integer> numbers = new ArrayList<Integer>();
+ for (int i = 0;i < 4;i++) {
+ numbers.add(1);
+ }
+ assertTrue(renderer.hasValidArguments("vhcurveto", numbers));
+ numbers.add(1);
+ assertTrue(renderer.hasValidArguments("vvcurveto", numbers));
+ for (int i = 0;i < 3;i++) {
+ numbers.add(1);
+ }
+ assertTrue(renderer.hasValidArguments("rcurveline", numbers));
+ }
+
+}
Index: fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java
===================================================================
--- fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java (revision 1546564)
+++ fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java (working copy)
@@ -27,7 +27,7 @@
/**
* This class creates all needed AFM font metric data from a CFFFont ready to be read from a AFMPaser.
- *
+ *
* @author Villu Ruusmann
* @version $Revision$
*/
@@ -125,7 +125,7 @@
metric.name = mapping.getName();
renderer.render(mapping.toType1Sequence());
metric.width = renderer.getWidth();
- metric.bounds = renderer.getBounds();
+ metric.bounds = renderer.getBounds2D();
metrics.add(metric);
}
return metrics;
@@ -150,7 +150,7 @@
}
/**
- * This class represents the metric of one single character.
+ * This class represents the metric of one single character.
*
*/
private static class CharMetric implements Comparable<CharMetric>
Index: fontbox/src/main/java/org/apache/fontbox/cff/CharStringRenderer.java
===================================================================
--- fontbox/src/main/java/org/apache/fontbox/cff/CharStringRenderer.java (revision 1546564)
+++ fontbox/src/main/java/org/apache/fontbox/cff/CharStringRenderer.java (working copy)
@@ -16,9 +16,11 @@
*/
package org.apache.fontbox.cff;
+import java.awt.Point;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
+import java.util.HashMap;
import java.util.List;
import org.apache.commons.logging.Log;
@@ -33,7 +35,7 @@
{
// TODO CharStringRenderer as abstract Class with two inherited classes according to the Charsstring type....
private static final Log LOG = LogFactory.getLog(CharStringRenderer.class);
-
+
private boolean isCharstringType1 = true;
private boolean isFirstCommand = true;
@@ -42,6 +44,8 @@
private Point2D referencePoint = null;
private int width = 0;
private boolean hasNonEndCharOp = false;
+ private int[] bbox = {0,0,0,0};
+ private HashMap<String, String> vStrings;
/**
* Constructor for the char string renderer.
@@ -100,7 +104,7 @@
private void handleCommandType2(List<Integer> numbers, CharStringCommand command)
{
String name = CharStringCommand.TYPE2_VOCABULARY.get(command.getKey());
-
+ checkArguments(name, numbers);
if (!hasNonEndCharOp)
{
hasNonEndCharOp = !"endchar".equals(name);
@@ -176,7 +180,7 @@
setWidth(numbers.get(0));
rmoveTo(numbers.get(1), numbers.get(2));
}
- else
+ else if (numbers.size() == 2)
{
rmoveTo(numbers.get(0), numbers.get(1));
}
@@ -192,7 +196,7 @@
setWidth(numbers.get(0));
rmoveTo(numbers.get(1), Integer.valueOf(0));
}
- else
+ else if (numbers.size() == 1)
{
rmoveTo(numbers.get(0), Integer.valueOf(0));
}
@@ -284,6 +288,61 @@
}
}
+ void checkArguments(String name, List<Integer> numbers) {
+ if (name == null) {
+ return;
+ }
+ boolean valid = hasValidArguments(name, numbers);
+ if (!valid) {
+ //Initialize the validation strings if not already done
+ if (vStrings == null) {
+ vStrings = new HashMap<String, String>();
+ vStrings.put("vmoveto", "1 || 2");
+ vStrings.put("rlineto", "3 || % 2");
+ vStrings.put("rrcurveto", "7 || % 6");
+ vStrings.put("rlinecurve", "% 2 || 6 + % 2");
+ vStrings.put("rcurveline", "% 6 || 2 + % 6");
+ vStrings.put("rmoveto", "2 || 3");
+ vStrings.put("hmoveto", "1 || 2");
+ vStrings.put("vhcurveto", "% 4 || 1 + % 4");
+ vStrings.put("hvcurveto", "% 4 || 1 + % 4");
+ vStrings.put("vvcurveto", "% 4 || 1 + % 4");
+ }
+ LOG.info(String.format("Font has an unexpected number of parameters for operator '%s'. Arguments "+
+ "size %d did not match pattern '%s'", name, numbers.size(),
+ vStrings.get(name)));
+ }
+ }
+
+ boolean hasValidArguments(String name, List<Integer> numbers) {
+ boolean valid = true;
+ if (name.equals("vmoveto")) {
+ valid = (numbers.size() == 1 || numbers.size() == 2);
+ }
+ if (name.equals("rlineto")) {
+ valid = (numbers.size() == 3 || numbers.size() % 2 == 0);
+ }
+ if (name.equals("rrcurveto")) {
+ valid = (numbers.size() == 7 || numbers.size() % 6 == 0);
+ }
+ if (name.equals("rlinecurve")) {
+ valid = (numbers.size() % 2 == 0 || (numbers.size() - 6) % 2 == 0);
+ }
+ if (name.equals("rcurveline")) {
+ valid = (numbers.size() % 6 == 0 || (numbers.size() - 2) % 6 == 0);
+ }
+ if (name.equals("rmoveto")) {
+ valid = (numbers.size() == 2 || numbers.size() == 3);
+ }
+ if (name.equals("hmoveto")) {
+ valid = (numbers.size() == 1 || numbers.size() == 2);
+ }
+ if (name.equals("vvcurveto") || name.equals("vhcurveto") || name.equals("hvcurveto")) {
+ valid = (numbers.size() % 4 == 0 || (numbers.size() - 1) % 4 == 0);
+ }
+ return valid;
+ }
+
/**
*
* @param numbers
@@ -353,11 +412,14 @@
Point2D point = referencePoint;
if (point == null)
{
- point = path.getCurrentPoint();
- if (point == null)
+ if (path.getCurrentPoint() == null)
{
point = sidebearingPoint;
}
+ else
+ {
+ point = path.getCurrentPoint();
+ }
}
referencePoint = null;
path.moveTo((float)(point.getX() + dx.doubleValue()),
@@ -397,15 +459,20 @@
private void rlineTo(Number dx, Number dy)
{
Point2D point = path.getCurrentPoint();
- path.lineTo((float)(point.getX() + dx.doubleValue()),
- (float)(point.getY() + dy.doubleValue()));
+ if (point != null) {
+ updateBBox(dx.intValue(), dy.intValue());
+ path.lineTo((float)(point.getX() + dx.doubleValue()),
+ (float)(point.getY() + dy.doubleValue()));
+ }
}
private void rrlineTo(List<Integer> numbers)
{
for (int i = 0;i < numbers.size();i += 2)
{
- rlineTo(numbers.get(i), numbers.get(i + 1));
+ if (numbers.size() - i >= 2) {
+ rlineTo(numbers.get(i), numbers.get(i + 1));
+ }
}
}
@@ -415,13 +482,15 @@
{
for (int i = 0;i < numbers.size();i += 6)
{
- float x1 = numbers.get(i);
- float y1 = numbers.get(i + 1);
- float x2 = numbers.get(i + 2);
- float y2 = numbers.get(i + 3);
- float x3 = numbers.get(i + 4);
- float y3 = numbers.get(i + 5);
- rrcurveTo(x1, y1, x2, y2, x3, y3);
+ if (numbers.size() - i >= 6) {
+ float x1 = numbers.get(i);
+ float y1 = numbers.get(i + 1);
+ float x2 = numbers.get(i + 2);
+ float y2 = numbers.get(i + 3);
+ float x3 = numbers.get(i + 4);
+ float y3 = numbers.get(i + 5);
+ rrcurveTo(x1, y1, x2, y2, x3, y3);
+ }
}
}
}
@@ -429,14 +498,42 @@
private void rrcurveTo(Number dx1, Number dy1, Number dx2, Number dy2,
Number dx3, Number dy3)
{
- Point2D point = path.getCurrentPoint();
- float x1 = (float) point.getX() + dx1.floatValue();
- float y1 = (float) point.getY() + dy1.floatValue();
- float x2 = x1 + dx2.floatValue();
- float y2 = y1 + dy2.floatValue();
- float x3 = x2 + dx3.floatValue();
- float y3 = y2 + dy3.floatValue();
- path.curveTo(x1, y1, x2, y2, x3, y3);
+ Point2D p0 = path.getCurrentPoint();
+ if (p0 != null) {
+ float x1 = (float) p0.getX() + dx1.floatValue();
+ float y1 = (float) p0.getY() + dy1.floatValue();
+ float x2 = x1 + dx2.floatValue();
+ float y2 = y1 + dy2.floatValue();
+ float x3 = x2 + dx3.floatValue();
+ float y3 = y2 + dy3.floatValue( );
+
+ Point p1 = new Point((int)x1, (int)y1);
+ Point p2 = new Point((int)x2, (int)y2);
+ Point p3 = new Point((int)x3, (int)y3);
+
+ updateBBox((int)p0.getX(), (int)p0.getY());
+ updateBBox((int)p3.getX(), (int)p3.getY());
+
+ int[] abc = calculateABC((int)p0.getX(), p1.x, p2.x, p3.x);
+ double[] txs = getT(abc);
+ for (double tx : txs) {
+ if (tx > 0 && tx < 1) {
+ int[] XandY = getXandY(tx, new Point((int)p0.getX(), (int)p0.getY()), p1, p2, p3);
+ updateBBox(XandY[0], XandY[1]);
+ }
+ }
+
+ abc = calculateABC((int)p0.getY(), p1.y, p2.y, p3.y);
+ double[] tys = getT(abc);
+ for (double ty : tys) {
+ if (ty > 0 && ty < 1) {
+ int[] XandY = getXandY(ty, new Point((int)p0.getX(), (int)p0.getY()), p1, p2, p3);
+ updateBBox(XandY[0], XandY[1]);
+ }
+ }
+
+ path.curveTo(x1, y1, x2, y2, x3, y3);
+ }
}
@@ -646,7 +743,9 @@
private void closePath()
{
referencePoint = path.getCurrentPoint();
- path.closePath();
+ if (referencePoint != null) {
+ path.closePath();
+ }
}
private void pointSb(Number x, Number y)
@@ -658,11 +757,15 @@
* Returns the bounds of the renderer path.
* @return the bounds as Rectangle2D
*/
- public Rectangle2D getBounds()
+ public int[] getBounds()
{
- return path.getBounds2D();
+ return bbox;
}
+ public Rectangle2D getBounds2D() {
+ return path.getBounds2D();
+ }
+
/**
* Returns the width of the current command.
* @return the width
@@ -676,4 +779,61 @@
{
this.width = aWidth;
}
-}
\ No newline at end of file
+
+ private int[] calculateABC(int p0, int p1, int p2, int p3) {
+ int[] abc = new int[3];
+ abc[0] = p0 - 3 * p1 + 3 * p2 - p3;
+ abc[1] = 2 * (-p0 + 2 * p1 - p2);
+ abc[2] = p0 - p1;
+ return abc;
+ }
+
+ private double[] getT(int[] abc) {
+ double[] t = {-1, -1};
+ int a = abc[0];
+ int b = abc[1];
+ int c = abc[2];
+ double s = Math.pow(b, 2) - 4 * a * c;
+ if (a == 0) {
+ if (b != 0) {
+ t[0] = -c / b;
+ }
+ return t;
+ } else if (s > 0) {
+ t[0] = (-b + Math.sqrt(s)) / 2 / a;
+ t[1] = (-b - Math.sqrt(s)) / 2 / a;
+ return t;
+ } else if (s == 0) {
+ t[0] = -b / 2 / a;
+ return t;
+ } else {
+ return t;
+ }
+ }
+
+ private int[] getXandY(double t, Point p0, Point p1, Point p2, Point p3) {
+ int[] XandY = new int[2];
+ double p0Coeff = Math.pow(1 - t, 3);
+ double p1Coeff = 3 * t * Math.pow(1 - t, 2);
+ double p2Coeff = 3 * Math.pow(t, 2) * (1 - t);
+ double p3Coeff = Math.pow(t, 3);
+ double x = p0Coeff * p0.x + p1Coeff * p1.x + p2Coeff * p2.x + p3Coeff * p3.x;
+ double y = p0Coeff * p0.y + p1Coeff * p1.y + p2Coeff * p2.y + p3Coeff * p3.y;
+ XandY[0] = (int)x;
+ XandY[1] = (int)y;
+ return XandY;
+ }
+
+ private void updateBBox(int x, int y) {
+ if (x < bbox[0]) {
+ bbox[0] = x;
+ } else if (x > bbox[2]) {
+ bbox[2] = x;
+ }
+ if (y < bbox[1]) {
+ bbox[1] = y;
+ } else if (y > bbox[3]) {
+ bbox[3] = y;
+ }
+ }
+}

+ 738
- 0
lib/pdfbox-1646.patch View File

@@ -0,0 +1,738 @@
Index: fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
===================================================================
--- fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java (revision 1546564)
+++ fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java (working copy)
@@ -36,7 +36,7 @@
import org.apache.fontbox.cff.encoding.CFFStandardEncoding;
/**
- * This class represents a parser for a CFF font.
+ * This class represents a parser for a CFF font.
* @author Villu Ruusmann
* @version $Revision: 1.0 $
*/
@@ -107,7 +107,11 @@
{
input.setPosition(0);
}
+ return parse(input);
+ }
+ public List<CFFFont> parse(CFFDataInput input) throws IOException {
+ this.input = input;
header = readHeader(input);
nameIndex = readIndexData(input);
topDictIndex = readIndexData(input);
@@ -119,6 +123,7 @@
{
CFFFont font = parseFont(i);
font.setGlobalSubrIndex(globalSubrIndex);
+ font.constructMappings();
fonts.add(font);
}
return fonts;
@@ -145,7 +150,7 @@
return cffHeader;
}
- private static IndexData readIndexData(CFFDataInput input) throws IOException
+ public static IndexData readIndexData(CFFDataInput input) throws IOException
{
int count = input.readCard16();
IndexData index = new IndexData(count);
@@ -179,7 +184,8 @@
return dict;
}
- private static DictData.Entry readEntry(CFFDataInput input) throws IOException
+ private static DictData.Entry readEntry(CFFDataInput input)
+ throws IOException
{
DictData.Entry entry = new DictData.Entry();
while (true)
@@ -211,13 +217,15 @@
return entry;
}
- private static CFFOperator readOperator(CFFDataInput input, int b0) throws IOException
+ private static CFFOperator readOperator(CFFDataInput input, int b0)
+ throws IOException
{
CFFOperator.Key key = readOperatorKey(input, b0);
return CFFOperator.getOperator(key);
}
- private static CFFOperator.Key readOperatorKey(CFFDataInput input, int b0) throws IOException
+ private static CFFOperator.Key readOperatorKey(CFFDataInput input, int b0)
+ throws IOException
{
if (b0 == 12)
{
@@ -227,7 +235,8 @@
return new CFFOperator.Key(b0);
}
- private static Integer readIntegerNumber(CFFDataInput input, int b0) throws IOException
+ private static Integer readIntegerNumber(CFFDataInput input, int b0)
+ throws IOException
{
if (b0 == 28)
{
@@ -263,7 +272,8 @@
}
}
- private static Double readRealNumber(CFFDataInput input, int b0) throws IOException
+ private static Double readRealNumber(CFFDataInput input, int b0)
+ throws IOException
{
StringBuffer sb = new StringBuffer();
boolean done = false;
@@ -446,9 +456,9 @@
throw new IOException("FDArray is missing for a CIDKeyed Font.");
}
- int fontDictOffset = fdArrayEntry.getNumber(0).intValue();
- input.setPosition(fontDictOffset);
- IndexData fdIndex = readIndexData(input);
+ int fontDictOffset = fdArrayEntry.getNumber(0).intValue();
+ input.setPosition(fontDictOffset);
+ IndexData fdIndex = readIndexData(input);
List<Map<String, Object>> privateDictionaries = new LinkedList<Map<String, Object>>();
List<Map<String, Object>> fontDictionaries = new LinkedList<Map<String, Object>>();
@@ -577,8 +587,8 @@
{
return CFFStandardString.getName(index);
}
- if (index - 391 <= stringIndex.getCount())
- {
+ if (index - 391 < stringIndex.getCount())
+ {
DataInput dataInput = new DataInput(stringIndex.getBytes(index - 391));
return dataInput.getString();
}
@@ -620,7 +630,8 @@
return entry != null ? entry.getArray() : defaultValue;
}
- private CFFEncoding readEncoding(CFFDataInput dataInput, int[] gids) throws IOException
+ private CFFEncoding readEncoding(CFFDataInput dataInput, int[] gids)
+ throws IOException
{
int format = dataInput.readCard8();
int baseFormat = format & 0x7f;
@@ -639,7 +650,8 @@
}
}
- private Format0Encoding readFormat0Encoding(CFFDataInput dataInput, int format, int[] gids) throws IOException
+ private Format0Encoding readFormat0Encoding(CFFDataInput dataInput, int format,
+ int[] gids) throws IOException
{
Format0Encoding encoding = new Format0Encoding();
encoding.format = format;
@@ -657,7 +669,8 @@
return encoding;
}
- private Format1Encoding readFormat1Encoding(CFFDataInput dataInput, int format, int[] gids) throws IOException
+ private Format1Encoding readFormat1Encoding(CFFDataInput dataInput, int format,
+ int[] gids) throws IOException
{
Format1Encoding encoding = new Format1Encoding();
encoding.format = format;
@@ -683,7 +696,8 @@
return encoding;
}
- private void readSupplement(CFFDataInput dataInput, EmbeddedEncoding encoding) throws IOException
+ private void readSupplement(CFFDataInput dataInput, EmbeddedEncoding encoding)
+ throws IOException
{
encoding.nSups = dataInput.readCard8();
encoding.supplement = new EmbeddedEncoding.Supplement[encoding.nSups];
@@ -738,15 +752,14 @@
fdselect.fds = new int[nGlyphs];
for (int i = 0; i < fdselect.fds.length; i++)
{
- fdselect.fds[i] = dataInput.readCard8();
-
+ fdselect.fds[i] = dataInput.readCard8();
}
return fdselect;
}
/**
* Read the Format 3 of the FDSelect data structure.
- *
+ *
* @param dataInput
* @param format
* @param nGlyphs
@@ -768,7 +781,6 @@
r3.first = dataInput.readCard16();
r3.fd = dataInput.readCard8();
fdselect.range3[i] = r3;
-
}
fdselect.sentinel = dataInput.readCard16();
@@ -902,7 +914,8 @@
}
}
- private CFFCharset readCharset(CFFDataInput dataInput, int nGlyphs) throws IOException
+ private CFFCharset readCharset(CFFDataInput dataInput, int nGlyphs)
+ throws IOException
{
int format = dataInput.readCard8();
if (format == 0)
@@ -923,7 +936,8 @@
}
}
- private Format0Charset readFormat0Charset(CFFDataInput dataInput, int format, int nGlyphs) throws IOException
+ private Format0Charset readFormat0Charset(CFFDataInput dataInput, int format,
+ int nGlyphs) throws IOException
{
Format0Charset charset = new Format0Charset();
charset.format = format;
@@ -936,7 +950,8 @@
return charset;
}
- private Format1Charset readFormat1Charset(CFFDataInput dataInput, int format, int nGlyphs) throws IOException
+ private Format1Charset readFormat1Charset(CFFDataInput dataInput, int format,
+ int nGlyphs) throws IOException
{
Format1Charset charset = new Format1Charset();
charset.format = format;
@@ -957,7 +972,8 @@
return charset;
}
- private Format2Charset readFormat2Charset(CFFDataInput dataInput, int format, int nGlyphs) throws IOException
+ private Format2Charset readFormat2Charset(CFFDataInput dataInput, int format,
+ int nGlyphs) throws IOException
{
Format2Charset charset = new Format2Charset();
charset.format = format;
@@ -981,7 +997,7 @@
}
/**
- * Inner class holding the header of a CFF font.
+ * Inner class holding the header of a CFF font.
*/
private static class Header
{
@@ -999,7 +1015,7 @@
}
/**
- * Inner class holding the DictData of a CFF font.
+ * Inner class holding the DictData of a CFF font.
*/
private static class DictData
{
@@ -1030,7 +1046,7 @@
}
/**
- * {@inheritDoc}
+ * {@inheritDoc}
*/
public String toString()
{
@@ -1038,7 +1054,7 @@
}
/**
- * Inner class holding an operand of a CFF font.
+ * Inner class holding an operand of a CFF font.
*/
private static class Entry
{
@@ -1100,7 +1116,7 @@
}
/**
- * Inner class representing an embedded CFF encoding.
+ * Inner class representing an embedded CFF encoding.
*/
abstract static class EmbeddedEncoding extends CFFEncoding
{
@@ -1124,7 +1140,7 @@
}
/**
- * Inner class representing a supplement for an encoding.
+ * Inner class representing a supplement for an encoding.
*/
static class Supplement
{
@@ -1150,7 +1166,7 @@
}
/**
- * Inner class representing a Format0 encoding.
+ * Inner class representing a Format0 encoding.
*/
private static class Format0Encoding extends EmbeddedEncoding
{
@@ -1167,7 +1183,7 @@
}
/**
- * Inner class representing a Format1 encoding.
+ * Inner class representing a Format1 encoding.
*/
private static class Format1Encoding extends EmbeddedEncoding
{
@@ -1183,7 +1199,7 @@
}
/**
- * Inner class representing a range of an encoding.
+ * Inner class representing a range of an encoding.
*/
private static class Range1
{
@@ -1193,13 +1209,20 @@
@Override
public String toString()
{
- return getClass().getName() + "[first=" + first + ", nLeft=" + nLeft + "]";
+ return getClass().getName() + "[first=" + first + ", nLeft="
+ + nLeft + "]";
}
+
+ @Override
+ public boolean equals(Object obj) {
+ Range1 r = (Range1)obj;
+ return (first == r.first && nLeft == r.nLeft);
+ }
}
}
/**
- * Inner class representing an embedded CFF charset.
+ * Inner class representing an embedded CFF charset.
*/
abstract static class EmbeddedCharset extends CFFCharset
{
@@ -1211,7 +1234,7 @@
}
/**
- * Inner class representing a Format0 charset.
+ * Inner class representing a Format0 charset.
*/
private static class Format0Charset extends EmbeddedCharset
{
@@ -1226,7 +1249,7 @@
}
/**
- * Inner class representing a Format1 charset.
+ * Inner class representing a Format1 charset.
*/
private static class Format1Charset extends EmbeddedCharset
{
@@ -1240,7 +1263,7 @@
}
/**
- * Inner class representing a range of a charset.
+ * Inner class representing a range of a charset.
*/
private static class Range1
{
@@ -1256,7 +1279,7 @@
}
/**
- * Inner class representing a Format2 charset.
+ * Inner class representing a Format2 charset.
*/
private static class Format2Charset extends EmbeddedCharset
{
@@ -1270,7 +1293,7 @@
}
/**
- * Inner class representing a range of a charset.
+ * Inner class representing a range of a charset.
*/
private static class Range2
{
@@ -1284,4 +1307,8 @@
}
}
}
+
+ public IndexData getStringIndex() {
+ return stringIndex;
+ }
}
Index: fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
===================================================================
--- fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java (revision 1546564)
+++ fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java (working copy)
@@ -31,7 +31,7 @@
/**
* This class represents a CFF/Type2 Font.
- *
+ *
* @author Villu Ruusmann
* @version $Revision$
*/
@@ -44,6 +44,8 @@
private CFFEncoding fontEncoding = null;
private CFFCharset fontCharset = null;
private Map<String, byte[]> charStringsDict = new LinkedHashMap<String, byte[]>();
+ Map<Integer, Mapping> sidMappings = null;
+ ArrayList<Mapping> gidMappings = null;
private IndexData globalSubrIndex = null;
private IndexData localSubrIndex = null;
@@ -97,6 +99,7 @@
topDict.put(name, value);
}
}
+
/**
* Returns the top dictionary.
* @return the dictionary
@@ -107,7 +110,7 @@
}
/**
- * Adds the given key/value pair to the private dictionary.
+ * Adds the given key/value pair to the private dictionary.
* @param name the given key
* @param value the given value
*/
@@ -118,7 +121,8 @@
privateDict.put(name, value);
}
}
- /**
+
+ /**
* Returns the private dictionary.
* @return the dictionary
*/
@@ -127,14 +131,60 @@
return privateDict;
}
+ /**
+ * Returns a mapping for a given GID
+ * @param GID The given GID
+ * @return The found mapping
+ */
+ public Mapping getMapping(int GID) {
+ return sidMappings.get(GID);
+ }
+
/**
- * Get the mapping (code/SID/charname/bytes) for this font.
- * @return mappings for codes < 256 and for codes > = 256
- */
- public Collection<Mapping> getMappings()
+ * Get the mapping (code/SID/charname/bytes) for this font.
+ * @return mappings for codes < 256 and for codes > = 256
+ */
+ public Collection<Mapping> getMappings() {
+ constructMappings();
+ return sidMappings.values();
+ }
+
+ /**
+ * Gets the GID mappings list.
+ */
+ public ArrayList<Mapping> getGIDMappings() {
+ return gidMappings;
+ }
+
+ private void constructGIDMap() {
+ gidMappings = new ArrayList<Mapping>();
+ Mapping notdef = new Mapping();
+ notdef.setName(".notdef");
+ gidMappings.add(notdef);
+ for (CFFCharset.Entry entry : fontCharset.getEntries())
+ {
+ String name = entry.getName();
+ byte[] bytes = this.charStringsDict.get(name);
+ if (bytes == null)
+ {
+ continue;
+ }
+ Mapping mapping = new Mapping();
+ mapping.setSID(entry.getSID());
+ mapping.setName(name);
+ mapping.setBytes(bytes);
+ gidMappings.add(mapping);
+ }
+ }
+
+ /**
+ * Construct the mappings.
+ */
+ public void constructMappings()
{
- List<Mapping> mappings = new ArrayList<Mapping>();
- Set<String> mappedNames = new HashSet<String>();
+ constructGIDMap();
+ sidMappings = new LinkedHashMap<Integer, Mapping>();
+ Set<String> mappedNames = new HashSet<String>();
for (CFFEncoding.Entry entry : fontEncoding.getEntries())
{
String charName = fontCharset.getName(entry.getSID());
@@ -153,7 +203,7 @@
mapping.setSID(entry.getSID());
mapping.setName(charName);
mapping.setBytes(bytes);
- mappings.add(mapping);
+ sidMappings.put(mapping.getSID(), mapping);
mappedNames.add(charName);
}
if (fontEncoding instanceof CFFParser.EmbeddedEncoding)
@@ -177,7 +227,7 @@
mapping.setSID(supplement.getGlyph());
mapping.setName(charName);
mapping.setBytes(bytes);
- mappings.add(mapping);
+ sidMappings.put(mapping.getSID(), mapping);
mappedNames.add(charName);
}
}
@@ -185,7 +235,7 @@
int code = 256;
for (CFFCharset.Entry entry : fontCharset.getEntries())
{
- String name = entry.getName();
+ String name = entry.getName();
if (mappedNames.contains(name))
{
continue;
@@ -201,11 +251,10 @@
mapping.setName(name);
mapping.setBytes(bytes);
- mappings.add(mapping);
+ sidMappings.put(mapping.getSID(), mapping);
mappedNames.add(name);
}
- return mappings;
}
/**
@@ -215,34 +264,43 @@
* @return -1 if the SID is missing from the Font.
* @throws IOException
*/
- public int getWidth(int SID) throws IOException {
- int nominalWidth = privateDict.containsKey("nominalWidthX") ? ((Number)privateDict.get("nominalWidthX")).intValue() : 0;
- int defaultWidth = privateDict.containsKey("defaultWidthX") ? ((Number)privateDict.get("defaultWidthX")).intValue() : 1000 ;
-
- for (Mapping m : getMappings() ){
- if (m.getSID() == SID) {
+ public int getWidth(int SID) throws IOException {
+ int nominalWidth = privateDict.containsKey("nominalWidthX") ? ((Number) privateDict.get("nominalWidthX")).intValue() : 0;
+ int defaultWidth = privateDict.containsKey("defaultWidthX") ? ((Number) privateDict.get("defaultWidthX")).intValue() : 1000;
+ Mapping m = sidMappings.get(SID);
+ if (m != null) {
+ CharStringRenderer csr = getRendererForMapping(m);
+ // ---- If the CharString has a Width nominalWidthX must be added,
+ // otherwise it is the default width.
+ return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
+ }
- CharStringRenderer csr = null;
- if (((Number)getProperty("CharstringType")).intValue() == 2 ) {
- List<Object> lSeq = m.toType2Sequence();
- csr = new CharStringRenderer(false);
- csr.render(lSeq);
- } else {
- List<Object> lSeq = m.toType1Sequence();
- csr = new CharStringRenderer();
- csr.render(lSeq);
- }
+ // ---- SID Width not found, return the nodef width
+ return getNotDefWidth(defaultWidth, nominalWidth);
+ }
- // ---- If the CharString has a Width nominalWidthX must be added,
- // otherwise it is the default width.
- return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
- }
- }
+ private CharStringRenderer getRendererForMapping(Mapping m) throws IOException {
+ CharStringRenderer csr = null;
+ if (((Number) getProperty("CharstringType")).intValue() == 2) {
+ List<Object> lSeq = m.toType2Sequence();
+ csr = new CharStringRenderer(false);
+ csr.render(lSeq);
+ } else {
+ List<Object> lSeq = m.toType1Sequence();
+ csr = new CharStringRenderer();
+ csr.render(lSeq);
+ }
+ return csr;
+ }
- // ---- SID Width not found, return the nodef width
- return getNotDefWidth(defaultWidth, nominalWidth);
- }
-
+ /**
+ * Returns the witdth of the .notdef character.
+ *
+ * @param defaultWidth default width
+ * @param nominalWidth nominal width
+ * @return the calculated width for the .notdef character
+ * @throws IOException if something went wrong
+ */
protected int getNotDefWidth(int defaultWidth, int nominalWidth) throws IOException {
CharStringRenderer csr;
byte[] glyphDesc = this.getCharStringsDict().get(".notdef");
@@ -260,6 +318,36 @@
return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
}
+ /**
+ * Return the Width value of the given Glyph identifier
+ *
+ * @param SID
+ * @return -1 if the SID is missing from the Font.
+ * @throws IOException
+ */
+ public int[] getBoundingBox(int SID) throws IOException {
+ Mapping m = sidMappings.get(SID);
+ if (m != null) {
+ CharStringRenderer csr = getRendererForMapping(m);
+ return csr.getBounds();
+ }
+ // ---- SID Width not found, return the nodef width
+ return new int[4];
+ }
+
+ /**
+ * Gets the name of a character from the given SID
+ * @param SID The given SID
+ * @return The name of the found character
+ */
+ public String getNameOfCharFromCode(int SID) {
+ if (sidMappings.get(SID) != null) {
+ return sidMappings.get(SID).getName();
+ } else {
+ return "";
+ }
+ }
+
/**
* Returns the CFFEncoding of the font.
* @return the encoding
@@ -336,50 +424,51 @@
+ charStringsDict + "]";
}
+ /**
+ * Sets the global subroutine index data.
+ * @param globalSubrIndex the IndexData object containing the global subroutines
+ */
+ public void setGlobalSubrIndex(IndexData globalSubrIndexValue) {
+ globalSubrIndex = globalSubrIndexValue;
+ }
- /**
- * Sets the global subroutine index data.
- * @param globalSubrIndex the IndexData object containing the global subroutines
- */
- public void setGlobalSubrIndex(IndexData globalSubrIndex) {
- this.globalSubrIndex = globalSubrIndex;
- }
+ /**
+ * Returns the global subroutine index data.
+ * @return the dictionary
+ */
+ public IndexData getGlobalSubrIndex()
+ {
+ return globalSubrIndex;
+ }
- /**
- * Returns the global subroutine index data.
- * @return the dictionary
- */
- public IndexData getGlobalSubrIndex() {
- return globalSubrIndex;
- }
+ /**
+ * Returns the local subroutine index data.
+ * @return the dictionary
+ */
+ public IndexData getLocalSubrIndex()
+ {
+ return localSubrIndex;
+ }
- /**
- * Returns the local subroutine index data.
- * @return the dictionary
- */
- public IndexData getLocalSubrIndex() {
- return localSubrIndex;
- }
+ /**
+ * Sets the local subroutine index data.
+ * @param localSubrIndexValue the IndexData object containing the local subroutines
+ */
+ public void setLocalSubrIndex(IndexData localSubrIndexValue) {
+ localSubrIndex = localSubrIndexValue;
+ }
- /**
- * Sets the local subroutine index data.
- * @param localSubrIndex the IndexData object containing the local subroutines
- */
- public void setLocalSubrIndex(IndexData localSubrIndex) {
- this.localSubrIndex = localSubrIndex;
- }
+ /**
+ * This class is used for the font mapping.
+ *
+ */
+ public class Mapping
+ {
+ private int mappedCode;
+ private int mappedSID;
+ private String mappedName;
+ private byte[] mappedBytes;
- /**
- * This class is used for the font mapping.
- *
- */
- public class Mapping
- {
- private int mappedCode;
- private int mappedSID;
- private String mappedName;
- private byte[] mappedBytes;
-
/**
* Converts the mapping into a Type1-sequence.
* @return the Type1-sequence
@@ -458,4 +547,4 @@
this.mappedBytes = bytes;
}
}
-}
\ No newline at end of file
+}

BIN
lib/xmlgraphics-commons-svn-trunk.jar View File


+ 6
- 7
src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/GenerateBidiClass.java View File

@@ -32,7 +32,6 @@ import java.util.TreeSet;
import org.apache.fop.util.License;

// CSOFF: LineLength
// CSOFF: NoWhitespaceAfter

/**
* <p>Utility for generating a Java class representing bidirectional
@@ -303,7 +302,7 @@ public final class GenerateBidiClass {
sb.setLength(0);
out.println("private static byte[] bcL1 = {");
for (int i = 0; i < bcL1.length; i++) {
if (! first) {
if (!first) {
sb.append(",");
} else {
first = false;
@@ -327,7 +326,7 @@ public final class GenerateBidiClass {
sb.setLength(0);
out.println("private static byte[] bcR1 = {");
for (int i = 0; i < bcR1.length; i++) {
if (! first) {
if (!first) {
sb.append(",");
} else {
first = false;
@@ -351,7 +350,7 @@ public final class GenerateBidiClass {
sb.setLength(0);
out.println("private static int[] bcS1 = {");
for (int i = 0; i < bcS1.length; i++) {
if (! first) {
if (!first) {
sb.append(",");
} else {
first = false;
@@ -375,7 +374,7 @@ public final class GenerateBidiClass {
sb.setLength(0);
out.println("private static int[] bcE1 = {");
for (int i = 0; i < bcE1.length; i++) {
if (! first) {
if (!first) {
sb.append(",");
} else {
first = false;
@@ -399,7 +398,7 @@ public final class GenerateBidiClass {
sb.setLength(0);
out.println("private static byte[] bcC1 = {");
for (int i = 0; i < bcC1.length; i++) {
if (! first) {
if (!first) {
sb.append(",");
} else {
first = false;
@@ -434,7 +433,7 @@ public final class GenerateBidiClass {
if (k >= 0) {
return ca [ k ];
} else {
k = - (k + 1);
k = -(k + 1);
if (k == 0) {
return BidiConstants.L;
} else if (ch <= ea [ k - 1 ]) {

+ 22
- 26
src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/GenerateBidiTestData.java View File

@@ -40,10 +40,6 @@ import java.util.TreeMap;
import org.apache.fop.util.License;

// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: SimplifyBooleanReturnCheck
// CSOFF: EmptyForIteratorPadCheck

/**
* <p>Utility for generating a Java class and associated data files representing
@@ -202,7 +198,7 @@ public final class GenerateBidiTestData {
String ucName = sa[1];
if (isBlockStart(ucName)) {
String ucBlock = getBlockName(ucName);
if (! im.containsKey(ucBlock)) {
if (!im.containsKey(ucBlock)) {
im.put(ucBlock, new int[] { uc, -1, bc });
} else {
throw new IllegalArgumentException("duplicate start of block '" + ucBlock + "' at entry: " + line);
@@ -223,7 +219,7 @@ public final class GenerateBidiTestData {
} else {
Integer k = Integer.valueOf(bc);
List sl;
if (! sm.containsKey(k)) {
if (!sm.containsKey(k)) {
sl = new ArrayList();
sm.put(k, sl);
} else {
@@ -267,7 +263,7 @@ public final class GenerateBidiTestData {
}
}
// populate intervals from (block) interval map
if (! im.isEmpty()) {
if (!im.isEmpty()) {
for (Iterator it = im.values().iterator(); it.hasNext(); ) {
int[] ba = (int[]) it.next();
assert (ba != null) && (ba.length > 2);
@@ -335,7 +331,7 @@ public final class GenerateBidiTestData {
continue;
} else if (line.startsWith("#")) {
continue;
} else if (line.startsWith(PFX_TYPE) && ! ignoreDeprecatedTypeData) {
} else if (line.startsWith(PFX_TYPE) && !ignoreDeprecatedTypeData) {
List lines = new ArrayList();
if ((n = readType(line, b, lines)) < 0) {
break;
@@ -356,14 +352,14 @@ public final class GenerateBidiTestData {
// dump instrumentation
if (verbose) {
System.out.println();
if (! ignoreDeprecatedTypeData) {
if (!ignoreDeprecatedTypeData) {
System.out.println("Read type ranges : " + numTypeRanges);
}
System.out.println("Read level specs : " + numLevelSpecs);
System.out.println("Read test specs : " + numTestSpecs);
System.out.println("Read lines : " + lineNumber);
}
if (! ignoreDeprecatedTypeData) {
if (!ignoreDeprecatedTypeData) {
td = (int[][]) tdl.toArray(new int [ tdl.size() ] []);
}
ld = (int[][]) ldl.toArray(new int [ ldl.size() ] []);
@@ -378,12 +374,12 @@ public final class GenerateBidiTestData {
boolean done = false;
int n = 0;
lines.add(line);
while (! done) {
while (!done) {
switch (testPrefix(b, PFX_LEVELS)) {
case 0: // within current levels
if ((line = b.readLine()) != null) {
n++;
if ((line.length() > 0) && ! line.startsWith("#")) {
if ((line.length() > 0) && !line.startsWith("#")) {
lines.add(line);
}
} else {
@@ -509,7 +505,7 @@ public final class GenerateBidiTestData {
CharacterIterator ci = new StringCharacterIterator(charRanges);
// read initial list delimiter
skipSpace(ci);
if (! readStartOfList(ci)) {
if (!readStartOfList(ci)) {
badRangeSpec("missing initial list delimiter", charRanges);
}
// read negation token if present
@@ -538,7 +534,7 @@ public final class GenerateBidiTestData {
String s;
skipSpace(ci);
if ((s = maybeReadSeparator(ci)) != null) {
if ((s.length() != 0) && ! s.equals("||")) {
if ((s.length() != 0) && !s.equals("||")) {
badRangeSpec("invalid item separator \"" + s + "\"", charRanges);
}
}
@@ -557,10 +553,10 @@ public final class GenerateBidiTestData {
}
// read terminating list delimiter
skipSpace(ci);
if (! readEndOfList(ci)) {
if (!readEndOfList(ci)) {
badRangeSpec("missing terminating list delimiter", charRanges);
}
if (! atEnd(ci)) {
if (!atEnd(ci)) {
badRangeSpec("extraneous content prior to end of line", ci);
}
if (negated) {
@@ -578,9 +574,9 @@ public final class GenerateBidiTestData {
}

private static void skipSpace(CharacterIterator ci) {
while (! atEnd(ci)) {
while (!atEnd(ci)) {
char c = ci.current();
if (! Character.isWhitespace(c)) {
if (!Character.isWhitespace(c)) {
break;
} else {
ci.next();
@@ -589,7 +585,7 @@ public final class GenerateBidiTestData {
}

private static boolean maybeReadNext(CharacterIterator ci, char next) {
while (! atEnd(ci)) {
while (!atEnd(ci)) {
char c = ci.current();
if (c == next) {
ci.next();
@@ -906,7 +902,7 @@ public final class GenerateBidiTestData {
List ll = new ArrayList();
// read prefix
skipSpace(ci);
if (! maybeReadToken(ci, PFX_LEVELS)) {
if (!maybeReadToken(ci, PFX_LEVELS)) {
badLevelSpec("missing prefix \"" + PFX_LEVELS + "\"", ci);
}
// read level values
@@ -924,7 +920,7 @@ public final class GenerateBidiTestData {
}
// read to end of line
skipSpace(ci);
if (! atEnd(ci)) {
if (!atEnd(ci)) {
badLevelSpec("extraneous content prior to end of line", ci);
}
if (ll.size() == 0) {
@@ -1007,7 +1003,7 @@ public final class GenerateBidiTestData {
List rl = new ArrayList();
// read prefix
skipSpace(ci);
if (! maybeReadToken(ci, PFX_REORDER)) {
if (!maybeReadToken(ci, PFX_REORDER)) {
badReorderSpec("missing prefix \"" + PFX_REORDER + "\"", ci);
}
// read reorder values
@@ -1023,7 +1019,7 @@ public final class GenerateBidiTestData {
}
// read to end of line
skipSpace(ci);
if (! atEnd(ci)) {
if (!atEnd(ci)) {
badReorderSpec("extraneous content prior to end of line", ci);
}
return createReorderArray(rl, levels);
@@ -1066,7 +1062,7 @@ public final class GenerateBidiTestData {
CharacterIterator ci = new StringCharacterIterator(line);
List cl = new ArrayList();
// read bidi class identifier sequence
while (! atEnd(ci) && ! maybeReadNext(ci, ';')) {
while (!atEnd(ci) && !maybeReadNext(ci, ';')) {
skipSpace(ci);
int bc;
if ((bc = maybeReadBidiClass(ci)) >= 0) {
@@ -1086,7 +1082,7 @@ public final class GenerateBidiTestData {
}
// read to end of line
skipSpace(ci);
if (! atEnd(ci)) {
if (!atEnd(ci)) {
badTestSpec("extraneous content prior to end of line", ci);
}
return createTestArray(cl, bs, levels);
@@ -1244,7 +1240,7 @@ public final class GenerateBidiTestData {
ok = false;
}
}
if (! ok) {
if (!ok) {
System.out.println("Usage: GenerateBidiTestData [-v] [-i] [-d <ucdFile>] [-b <bidiFile>] [-o <outputFile>]");
System.out.println(" defaults:");
if (ignoreDeprecatedTypeData) {

+ 1
- 0
src/documentation/intermediate-format-ng/fop-intermediate-format-ng-content.xsd View File

@@ -38,6 +38,7 @@
<xs:complexContent>
<xs:extension base="mf:contentType">
<xs:attribute name="transform" type="xs:string"/>
<xs:attribute name="layer" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>

+ 1
- 0
src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory View File

@@ -1,3 +1,4 @@
org.apache.fop.render.afp.extensions.AFPExtensionHandlerFactory
org.apache.fop.render.pdf.extensions.PDFExtensionHandlerFactory
org.apache.fop.render.ps.extensions.PSExtensionHandlerFactory
org.apache.fop.fo.extensions.xmp.XMPContentHandlerFactory

+ 3
- 2
src/java/org/apache/fop/Version.java View File

@@ -40,8 +40,9 @@ public final class Version {
}
if (version == null) {
//Fallback if FOP is used in a development environment
String headURL
= "$HeadURL$";
// CSOFF: LineLength
String headURL = "$HeadURL$";
// CSON: LineLength
version = headURL;
final String pathPrefix = "/xmlgraphics/fop/";
int pos = version.indexOf(pathPrefix);

+ 1
- 1
src/java/org/apache/fop/apps/FOUserAgent.java View File

@@ -408,7 +408,7 @@ public class FOUserAgent {
try {
// Have to do this so we can resolve data URIs
StreamSource src = new StreamSource(resourceResolver.getResource(uri));
src.setSystemId(uri);
src.setSystemId(new File(uri).toURI().toURL().toExternalForm());
return src;
} catch (URISyntaxException use) {
return null;

+ 36
- 17
src/java/org/apache/fop/apps/FopConfParser.java View File

@@ -70,16 +70,7 @@ public class FopConfParser {
*/
public FopConfParser(InputStream fopConfStream, EnvironmentProfile enviro)
throws SAXException, IOException {
DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
Configuration cfg;
try {
cfg = cfgBuilder.build(fopConfStream);
} catch (ConfigurationException e) {
throw new FOPException(e);
}
// The default base URI is taken from the directory in which the fopConf resides
fopFactoryBuilder = new FopFactoryBuilder(enviro).setConfiguration(cfg);
configure(enviro.getDefaultBaseURI(), enviro.getResourceResolver(), cfg);
this(fopConfStream, enviro.getDefaultBaseURI(), enviro);
}

/**
@@ -94,7 +85,8 @@ public class FopConfParser {
*/
public FopConfParser(InputStream fopConfStream, URI defaultBaseURI,
ResourceResolver resourceResolver) throws SAXException, IOException {
this(fopConfStream, EnvironmentalProfileFactory.createDefault(defaultBaseURI, resourceResolver));
this(fopConfStream, defaultBaseURI,
EnvironmentalProfileFactory.createDefault(defaultBaseURI, resourceResolver));
}

/**
@@ -122,6 +114,20 @@ public class FopConfParser {
this(fopConfFile, ResourceResolverFactory.createDefaultResourceResolver());
}

/**
* Constructor that takes the FOP conf and a default base URI and uses the default URI resolver.
*
* @param fopConfFile the FOP conf file
* @param defaultBaseURI the default base URI
* @throws SAXException if a SAX error was thrown parsing the FOP conf
* @throws IOException if an I/O error is thrown while parsing the FOP conf
*/
public FopConfParser(File fopConfFile, URI defaultBaseURI) throws SAXException, IOException {
this(new FileInputStream(fopConfFile), fopConfFile.toURI(),
EnvironmentalProfileFactory.createDefault(defaultBaseURI,
ResourceResolverFactory.createDefaultResourceResolver()));
}

/**
* Constructor that parses the FOP conf and uses the URI resolver given.
*
@@ -132,11 +138,24 @@ public class FopConfParser {
*/
public FopConfParser(File fopConfFile, ResourceResolver resourceResolver)
throws SAXException, IOException {
this(new FileInputStream(fopConfFile),
fopConfFile.getAbsoluteFile().getParentFile().toURI(), resourceResolver);
this(new FileInputStream(fopConfFile), fopConfFile.toURI(), resourceResolver);
}

private FopConfParser(InputStream fopConfStream, URI baseURI, EnvironmentProfile enviro)
throws SAXException, IOException {
DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
Configuration cfg;
try {
cfg = cfgBuilder.build(fopConfStream);
} catch (ConfigurationException e) {
throw new FOPException(e);
}
// The default base URI is taken from the directory in which the fopConf resides
fopFactoryBuilder = new FopFactoryBuilder(enviro).setConfiguration(cfg);
configure(baseURI, enviro.getResourceResolver(), cfg);
}

private void configure(final URI defaultBaseURI, final ResourceResolver resourceResolver,
private void configure(final URI baseURI, final ResourceResolver resourceResolver,
Configuration cfg) throws FOPException {
if (log.isDebugEnabled()) {
log.debug("Initializing FopFactory Configuration");
@@ -174,7 +193,7 @@ public class FopConfParser {
if (cfg.getChild("base", false) != null) {
try {
URI confUri = InternalResourceResolver.getBaseURI(cfg.getChild("base").getValue(null));
fopFactoryBuilder.setBaseURI(defaultBaseURI.resolve(confUri));
fopFactoryBuilder.setBaseURI(baseURI.resolve(confUri));
} catch (URISyntaxException use) {
LogUtil.handleException(log, use, strict);
}
@@ -242,8 +261,8 @@ public class FopConfParser {
}

// configure font manager
new FontManagerConfigurator(cfg, fopFactoryBuilder.getBaseURI(), resourceResolver).configure(
fopFactoryBuilder.getFontManager(), strict);
new FontManagerConfigurator(cfg, baseURI, fopFactoryBuilder.getBaseURI(), resourceResolver)
.configure(fopFactoryBuilder.getFontManager(), strict);

// configure image loader framework
configureImageLoading(cfg.getChild("image-loading", false), strict);

+ 18
- 1
src/java/org/apache/fop/area/AreaTreeParser.java View File

@@ -62,6 +62,7 @@ import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.Trait.Background;
import org.apache.fop.area.Trait.InternalLink;
import org.apache.fop.area.inline.AbstractTextArea;
import org.apache.fop.area.inline.Container;
import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.InlineArea;
@@ -195,6 +196,7 @@ public class AreaTreeParser {
makers.put("space", new SpaceMaker());
makers.put("leader", new LeaderMaker());
makers.put("viewport", new InlineViewportMaker());
makers.put("container", new ContainerMaker());
makers.put("image", new ImageMaker());
makers.put("foreignObject", new ForeignObjectMaker());
makers.put("bookmarkTree", new BookmarkTreeMaker());
@@ -863,6 +865,21 @@ public class AreaTreeParser {
}
}

private class ContainerMaker extends AbstractMaker {

public void startElement(Attributes attributes) {
Container container = new Container();
transferForeignObjects(attributes, container);
InlineViewport parent = (InlineViewport) areaStack.peek();
parent.setContent(container);
areaStack.push(container);
}

public void endElement() {
assertObjectOfClass(areaStack.pop(), Container.class);
}
}

private class InlineViewportMaker extends AbstractMaker {

public void startElement(Attributes attributes) {
@@ -1040,7 +1057,7 @@ public class AreaTreeParser {
}

private static final Object[] SUBSET_COMMON = new Object[] {
Trait.PROD_ID};
Trait.PROD_ID, Trait.LAYER};
private static final Object[] SUBSET_LINK = new Object[] {
Trait.INTERNAL_LINK, Trait.EXTERNAL_LINK};
private static final Object[] SUBSET_COLOR = new Object[] {

+ 1
- 1
src/java/org/apache/fop/area/Footnote.java View File

@@ -83,7 +83,7 @@ public class Footnote extends BlockParent {
@Override
public void addBlock(Block child) {
addChildArea(child);
this.setBPD(this.getBPD() + child.getBPD());
setBPD(getBPD() + child.getAllocBPD());
}

}

+ 4
- 1
src/java/org/apache/fop/area/Trait.java View File

@@ -169,9 +169,11 @@ public final class Trait implements Serializable {
/** shift direction trait */
public static final Integer SHIFT_DIRECTION = 42;

/** For optional content groups. */
public static final Integer LAYER = 43;

/** Maximum value used by trait keys */
public static final int MAX_TRAIT_KEY = 42;
public static final int MAX_TRAIT_KEY = 43;

private static final TraitInfo[] TRAIT_INFO = new TraitInfo[MAX_TRAIT_KEY + 1];

@@ -243,6 +245,7 @@ public final class Trait implements Serializable {
new TraitInfo("block-progression-direction", Direction.class));
put(SHIFT_DIRECTION,
new TraitInfo("shift-direction", Direction.class));
put(LAYER, new TraitInfo("layer", String.class));

}


+ 7
- 8
src/java/org/apache/fop/area/inline/Container.java View File

@@ -51,13 +51,12 @@ public class Container extends Area {
public Container() {
}

/**
* Add the block to this area.
*
* @param block the block area to add
*/
public void addBlock(Block block) {
blocks.add(block);
@Override
public void addChildArea(Area child) {
if (!(child instanceof Block)) {
throw new IllegalArgumentException("Container only accepts block areas");
}
blocks.add((Block) child);
}

/**
@@ -65,7 +64,7 @@ public class Container extends Area {
*
* @return the list of block areas
*/
public List getBlocks() {
public List<Block> getBlocks() {
return blocks;
}


+ 4
- 40
src/java/org/apache/fop/cli/CommandLineOptions.java View File

@@ -58,7 +58,6 @@ import org.apache.fop.render.pdf.PDFEncryptionOption;
import org.apache.fop.render.print.PagesMode;
import org.apache.fop.render.print.PrintRenderer;
import org.apache.fop.render.xml.XMLRenderer;
import org.apache.fop.util.CommandLineLogger;

/**
* Options parses the commandline arguments
@@ -145,16 +144,6 @@ public class CommandLineOptions {
* Construct a command line option object.
*/
public CommandLineOptions() {
LogFactory logFactory = LogFactory.getFactory();

// Enable the simple command line logging when no other logger is
// defined.
if (System.getProperty("org.apache.commons.logging.Log") == null) {
logFactory.setAttribute("org.apache.commons.logging.Log",
CommandLineLogger.class.getName());
setLogLevel("info");
}

log = LogFactory.getLog("FOP");
}

@@ -184,9 +173,6 @@ public class CommandLineOptions {
//Factory config is set up, now we can create the user agent
foUserAgent = factory.newFOUserAgent();
foUserAgent.getRendererOptions().putAll(renderingOptions);
if (targetResolution != 0) {
foUserAgent.setTargetResolution(targetResolution);
}
addXSLTParameter("fop-output-format", getOutputFormat());
addXSLTParameter("fop-version", Version.getVersion());
foUserAgent.setConserveMemoryPolicy(conserveMemoryPolicy);
@@ -292,7 +278,7 @@ public class CommandLineOptions {
} else if (args[i].equals("-s")) {
suppressLowLevelAreas = Boolean.TRUE;
} else if (args[i].equals("-d")) {
setLogOption("debug", "debug");
// nop. Left there for backwards compatibility
} else if (args[i].equals("-r")) {
strictValidation = false;
} else if (args[i].equals("-conserve")) {
@@ -304,7 +290,7 @@ public class CommandLineOptions {
} else if (args[i].equals("-dpi")) {
i = i + parseResolution(args, i);
} else if (args[i].equals("-q") || args[i].equals("--quiet")) {
setLogOption("quiet", "error");
// nop. Left there for backwards compatibility
} else if (args[i].equals("-fo")) {
i = i + parseFOInputOption(args, i);
} else if (args[i].equals("-xsl")) {
@@ -904,27 +890,6 @@ public class CommandLineOptions {
}
}

private void setLogOption(String option, String level) {
if (log instanceof CommandLineLogger
|| System.getProperty("org.apache.commons.logging.Log") == null) {
setLogLevel(level);
} else if (log != null) {
log.warn("The option " + option + " can only be used");
log.warn("with FOP's command line logger,");
log.warn("which is the default on the command line.");
log.warn("Configure other loggers using Java system properties.");
}
}

private void setLogLevel(String level) {
// Set the level for future loggers.
LogFactory.getFactory().setAttribute("level", level);
if (log instanceof CommandLineLogger) {
// Set the level for the logger created already.
((CommandLineLogger) log).setLogLevel(level);
}
}

private void setInputFormat(int format) throws FOPException {
if (inputmode == NOT_SET || inputmode == format) {
inputmode = format;
@@ -1050,7 +1015,8 @@ public class CommandLineOptions {
fopFactoryBuilder.setComplexScriptFeatures(useComplexScriptFeatures);
} else {
try {
fopFactoryBuilder = new FopConfParser(userConfigFile).getFopFactoryBuilder();
FopConfParser fopConfParser = new FopConfParser(userConfigFile, baseURI);
fopFactoryBuilder = fopConfParser.getFopFactoryBuilder();
} catch (SAXException e) {
throw new FOPException(e);
}
@@ -1208,9 +1174,7 @@ public class CommandLineOptions {
+ "[-awt|-pdf|-mif|-rtf|-tiff|-png|-pcl|-ps|-txt|-at [mime]|-print] <outfile>\n"
+ " [OPTIONS] \n"
+ " -version print FOP version and exit\n"
+ " -d debug mode \n"
+ " -x dump configuration settings \n"
+ " -q quiet mode \n"
+ " -c cfg.xml use additional configuration file cfg.xml\n"
+ " -l lang the language to use for user information \n"
+ " -nocs disable complex script features\n"

+ 0
- 1
src/java/org/apache/fop/complexscripts/bidi/BidiClass.java View File

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

import java.util.Arrays;

// CSOFF: WhitespaceAfterCheck
// CSOFF: LineLengthCheck

/*

+ 3
- 7
src/java/org/apache/fop/complexscripts/bidi/BidiResolver.java View File

@@ -32,11 +32,7 @@ import org.apache.fop.area.LineArea;
import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.fo.pagination.PageSequence;

// CSOFF: EmptyForIteratorPadCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: SimplifyBooleanReturnCheck

/**
* <p>A utility class for performing bidirectional resolution processing.</p>
@@ -140,7 +136,7 @@ public final class BidiResolver {
runsNew.addAll(ir.split());
}
}
if (! runsNew.equals(runs)) {
if (!runsNew.equals(runs)) {
runs = runsNew;
}
return runs;
@@ -180,7 +176,7 @@ public final class BidiResolver {
i = e - 1;
}
}
if (! runsNew.equals(runs)) {
if (!runsNew.equals(runs)) {
runs = runsNew;
}
return runs;
@@ -232,7 +228,7 @@ public final class BidiResolver {
Vector rv = new Vector();
for (Iterator it = ranges.iterator(); it.hasNext(); ) {
DelimitedTextRange r = (DelimitedTextRange) it.next();
if (! r.isEmpty()) {
if (!r.isEmpty()) {
rv.add(r);
}
}

+ 1
- 4
src/java/org/apache/fop/complexscripts/bidi/DelimitedTextRange.java View File

@@ -34,10 +34,7 @@ import org.apache.fop.traits.WritingModeTraits;
import org.apache.fop.traits.WritingModeTraitsGetter;
import org.apache.fop.util.CharUtilities;

// CSOFF: EmptyForIteratorPadCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck

/**
* The <code>DelimitedTextRange</code> class implements the "delimited text range" as described
@@ -151,7 +148,7 @@ public class DelimitedTextRange {
TextInterval ti = (TextInterval) it.next();
intervalsNew.addAll(assignLevels(ti, levels));
}
if (! intervalsNew.equals(intervals)) {
if (!intervalsNew.equals(intervals)) {
intervals = intervalsNew;
}
}

+ 2
- 9
src/java/org/apache/fop/complexscripts/bidi/InlineRun.java View File

@@ -35,11 +35,6 @@ import org.apache.fop.area.inline.UnresolvedPageNumber;
import org.apache.fop.area.inline.WordArea;
import org.apache.fop.util.CharUtilities;

// CSOFF: EmptyForIteratorPadCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: SimplifyBooleanReturnCheck

/**
* The <code>InlineRun</code> class is a utility class, the instances of which are used
* to capture a sequence of reordering levels associated with an inline area.
@@ -179,7 +174,7 @@ public class InlineRun {
if (inline instanceof WordArea) {
WordArea w = (WordArea) inline;
// if not already reversed, then reverse now
if (! w.isReversed()) {
if (!w.isReversed()) {
if ((reversals & 1) != 0) {
w.reverse(mirror);
} else if (mirror && maybeNeedsMirroring()) {
@@ -209,10 +204,8 @@ public class InlineRun {
}
return true;
}
} else if ((ir.levels == null) && (levels == null)) {
return true;
} else {
return false;
return (ir.levels == null) && (levels == null);
}
} else {
return false;

+ 1
- 4
src/java/org/apache/fop/complexscripts/bidi/TextInterval.java View File

@@ -28,7 +28,6 @@ import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.flow.Leader;

// CSOFF: LineLengthCheck
// CSOFF: SimplifyBooleanReturnCheck

/**
* <p>The <code>TextInterval</code> class is a utility class, the instances of which are used
@@ -102,10 +101,8 @@ class TextInterval {
return false;
} else if (ti.getStart() != start) {
return false;
} else if (ti.getEnd() != end) {
return false;
} else {
return true;
return ti.getEnd() == end;
}
} else {
return false;

+ 12
- 17
src/java/org/apache/fop/complexscripts/bidi/UnflattenProcessor.java View File

@@ -35,10 +35,7 @@ import org.apache.fop.area.inline.SpaceArea;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.area.inline.UnresolvedPageNumber;

// CSOFF: EmptyForIteratorPadCheck
// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: SimplifyBooleanReturnCheck

/**
* <p>The <code>UnflattenProcessor</code> class is used to reconstruct (by unflattening) a line
@@ -86,10 +83,8 @@ class UnflattenProcessor {
private boolean shouldFinishTextContainer(TextArea tc, InlineArea ia) {
if ((tcOrig != null) && (tc != tcOrig)) {
return true;
} else if ((iaLevelLast != -1) && (ia.getBidiLevel() != iaLevelLast)) {
return true;
} else {
return false;
return (iaLevelLast != -1) && (ia.getBidiLevel() != iaLevelLast);
}
}
private void finishTextContainer() {
@@ -98,7 +93,7 @@ class UnflattenProcessor {
private void finishTextContainer(TextArea tc, InlineArea ia) {
if (tcNew != null) {
updateIPD(tcNew);
if (! icNew.empty()) {
if (!icNew.empty()) {
icNew.peek().addChildArea(tcNew);
} else {
ilNew.add(tcNew);
@@ -113,12 +108,12 @@ class UnflattenProcessor {
}
private boolean shouldFinishInlineContainer(List<InlineParent> ich, TextArea tc, InlineArea ia) {
if ((ich == null) || ich.isEmpty()) {
return ! icOrig.empty();
return !icOrig.empty();
} else {
if (! icOrig.empty()) {
if (!icOrig.empty()) {
InlineParent ic = ich.get(0);
InlineParent ic0 = icOrig.peek();
return (ic != ic0) && ! isInlineParentOf(ic, ic0);
return (ic != ic0) && !isInlineParentOf(ic, ic0);
} else {
return false;
}
@@ -128,14 +123,14 @@ class UnflattenProcessor {
finishInlineContainer(null, null, null);
}
private void finishInlineContainer(List<InlineParent> ich, TextArea tc, InlineArea ia) {
if ((ich != null) && ! ich.isEmpty()) { // finish non-matching inner inline container(s)
if ((ich != null) && !ich.isEmpty()) { // finish non-matching inner inline container(s)
for (Iterator<InlineParent> it = ich.iterator(); it.hasNext(); ) {
InlineParent ic = it.next();
InlineParent ic0 = icOrig.empty() ? null : icOrig.peek();
if (ic0 == null) {
assert icNew.empty();
} else if (ic != ic0) {
assert ! icNew.empty();
assert !icNew.empty();
InlineParent icO0 = icOrig.pop();
InlineParent icN0 = icNew.pop();
assert icO0 != null;
@@ -145,7 +140,7 @@ class UnflattenProcessor {
} else {
icNew.peek().addChildArea(icN0);
}
if (! icOrig.empty() && (icOrig.peek() == ic)) {
if (!icOrig.empty() && (icOrig.peek() == ic)) {
break;
}
} else {
@@ -153,7 +148,7 @@ class UnflattenProcessor {
}
}
} else { // finish all inline containers
while (! icNew.empty()) {
while (!icNew.empty()) {
InlineParent icO0 = icOrig.pop();
InlineParent icN0 = icNew.pop();
assert icO0 != null;
@@ -176,8 +171,8 @@ class UnflattenProcessor {
finishInlineContainer();
}
private void update(List<InlineParent> ich, TextArea tc, InlineArea ia) {
if (! alreadyUnflattened(ia)) {
if ((ich != null) && ! ich.isEmpty()) {
if (!alreadyUnflattened(ia)) {
if ((ich != null) && !ich.isEmpty()) {
pushInlineContainers(ich);
}
if (tc != null) {
@@ -345,7 +340,7 @@ class UnflattenProcessor {
Area a = ia.getParentArea();
while (a != null) {
if (a instanceof InlineArea) {
if ((a instanceof InlineParent) && ! (a instanceof TextArea)) {
if ((a instanceof InlineParent) && !(a instanceof TextArea)) {
ich.add((InlineParent) a);
}
a = ((InlineArea) a) .getParentArea();

+ 28
- 41
src/java/org/apache/fop/complexscripts/bidi/UnicodeBidiAlgorithm.java View File

@@ -25,12 +25,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.traits.Direction;
import org.apache.fop.util.CharUtilities;

// CSOFF: AvoidNestedBlocksCheck
// CSOFF: EmptyForIteratorPadCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: ParameterNumberCheck

/**
* <p>The <code>UnicodeBidiAlgorithm</code> class implements functionality prescribed by
@@ -125,47 +120,39 @@ public final class UnicodeBidiAlgorithm implements BidiConstants {
case RLE: // start right-to-left embedding
case LRO: // start left-to-right override
case RLO: // start right-to-left override
{
int en; /* new embedding level */
if ((bc == RLE) || (bc == RLO)) {
en = ((ec & ~OVERRIDE) + 1) | 1;
} else {
en = ((ec & ~OVERRIDE) + 2) & ~1;
}
if (en < (MAX_LEVELS + 1)) {
es [ ei++ ] = ec;
if ((bc == LRO) || (bc == RLO)) {
ec = en | OVERRIDE;
} else {
ec = en & ~OVERRIDE;
}
int en; /* new embedding level */
if ((bc == RLE) || (bc == RLO)) {
en = ((ec & ~OVERRIDE) + 1) | 1;
} else {
en = ((ec & ~OVERRIDE) + 2) & ~1;
}
if (en < (MAX_LEVELS + 1)) {
es [ ei++ ] = ec;
if ((bc == LRO) || (bc == RLO)) {
ec = en | OVERRIDE;
} else {
// max levels exceeded, so don't change level or override
ec = en & ~OVERRIDE;
}
el = ec;
break;
} else {
// max levels exceeded, so don't change level or override
}
el = ec;
break;
case PDF: // pop directional formatting
{
el = ec;
if (ei > 0) {
ec = es [ --ei ];
} else {
// ignore isolated PDF
}
break;
el = ec;
if (ei > 0) {
ec = es [ --ei ];
} else {
// ignore isolated PDF
}
break;
case B: // paragraph separator
{
el = ec = defaultLevel;
ei = 0;
break;
}
el = ec = defaultLevel;
ei = 0;
break;
default:
{
el = ec;
break;
}
el = ec;
break;
}
switch (bc) {
case BN:
@@ -608,7 +595,7 @@ public final class UnicodeBidiAlgorithm implements BidiConstants {

private static boolean isRetainedFormatting(int[] ca, int s, int e) {
for (int i = s; i < e; i++) {
if (! isRetainedFormatting(ca[i])) {
if (!isRetainedFormatting(ca[i])) {
return false;
}
}
@@ -680,7 +667,7 @@ public final class UnicodeBidiAlgorithm implements BidiConstants {
} else {
chOut = chIn;
}
if (! triggered && triggersBidi(chOut)) {
if (!triggered && triggersBidi(chOut)) {
triggered = true;
}
if ((chOut & 0xFF0000) == 0) {

+ 5
- 6
src/java/org/apache/fop/complexscripts/fonts/GlyphClassTable.java View File

@@ -23,7 +23,6 @@ import java.util.Iterator;
import java.util.List;

// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck

/**
* <p>Base class implementation of glyph class table.</p>
@@ -100,7 +99,7 @@ public final class GlyphClassTable extends GlyphMappingTable implements GlyphCla
} else {
for (Iterator it = entries.iterator(); it.hasNext();) {
Object o = it.next();
if (! (o instanceof Integer)) {
if (!(o instanceof Integer)) {
return false;
}
}
@@ -114,7 +113,7 @@ public final class GlyphClassTable extends GlyphMappingTable implements GlyphCla
} else {
for (Iterator it = entries.iterator(); it.hasNext();) {
Object o = it.next();
if (! (o instanceof MappingRange)) {
if (!(o instanceof MappingRange)) {
return false;
}
}
@@ -128,7 +127,7 @@ public final class GlyphClassTable extends GlyphMappingTable implements GlyphCla
} else {
for (Iterator it = entries.iterator(); it.hasNext();) {
Object o = it.next();
if (! (o instanceof GlyphCoverageTable)) {
if (!(o instanceof GlyphCoverageTable)) {
return false;
}
}
@@ -197,7 +196,7 @@ public final class GlyphClassTable extends GlyphMappingTable implements GlyphCla
if (it.hasNext()) {
Object o = it.next();
if (o instanceof Integer) {
firstGlyph = ((Integer) o) . intValue();
firstGlyph = ((Integer) o) .intValue();
} else {
throw new AdvancedTypographicTableFormatException("illegal entry, first entry must be Integer denoting first glyph value, but is: " + o);
}
@@ -210,7 +209,7 @@ public final class GlyphClassTable extends GlyphMappingTable implements GlyphCla
while (it.hasNext()) {
Object o = it.next();
if (o instanceof Integer) {
int gc = ((Integer) o) . intValue();
int gc = ((Integer) o) .intValue();
gca [ i++ ] = gc;
if (gc > gcMax) {
gcMax = gc;

+ 3
- 5
src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageTable.java View File

@@ -27,8 +27,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

// CSOFF: LineLengthCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: NoWhitespaceAfterCheck

/**
* <p>.Base class implementation of glyph coverage table.</p>
@@ -103,7 +101,7 @@ public final class GlyphCoverageTable extends GlyphMappingTable implements Glyph
} else {
for (Iterator it = entries.iterator(); it.hasNext();) {
Object o = it.next();
if (! (o instanceof Integer)) {
if (!(o instanceof Integer)) {
return false;
}
}
@@ -117,7 +115,7 @@ public final class GlyphCoverageTable extends GlyphMappingTable implements Glyph
} else {
for (Iterator it = entries.iterator(); it.hasNext();) {
Object o = it.next();
if (! (o instanceof MappingRange)) {
if (!(o instanceof MappingRange)) {
return false;
}
}
@@ -183,7 +181,7 @@ public final class GlyphCoverageTable extends GlyphMappingTable implements Glyph
for (Iterator it = entries.iterator(); it.hasNext();) {
Object o = it.next();
if (o instanceof Integer) {
int gid = ((Integer) o) . intValue();
int gid = ((Integer) o) .intValue();
if ((gid >= 0) && (gid < 65536)) {
if (gid > gidMax) {
map [ i++ ] = gidMax = gid;

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

@@ -20,7 +20,6 @@
package org.apache.fop.complexscripts.fonts;

// CSOFF: LineLengthCheck
// CSOFF: InnerAssignmentCheck

/**
* <p>The <code>GlyphDefinitionSubtable</code> implements an abstract base of a glyph definition subtable,

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

@@ -29,7 +29,6 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.complexscripts.scripts.ScriptProcessor;
import org.apache.fop.complexscripts.util.GlyphSequence;

// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck

/**

+ 1
- 3
src/java/org/apache/fop/complexscripts/fonts/GlyphMappingTable.java View File

@@ -23,8 +23,6 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

// CSOFF: NoWhitespaceAfterCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck

/**
@@ -162,7 +160,7 @@ public class GlyphMappingTable {
int mi;
if ((i = Arrays.binarySearch(sa, gid)) >= 0) {
mi = getMappedIndex(gid, sa [ i ], ma [ i ]); // matches start of (some) range
} else if ((i = - (i + 1)) == 0) {
} else if ((i = -(i + 1)) == 0) {
mi = -1; // precedes first range
} else if (gid > ea [ --i ]) {
mi = -1; // follows preceding (or last) range

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

@@ -23,7 +23,6 @@ import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.ScriptContextTester;

// CSOFF: LineLengthCheck
// CSOFF: ParameterNumberCheck

/**
* <p>The <code>GlyphPositioningState</code> implements an state object used during glyph positioning

+ 3
- 5
src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java View File

@@ -23,8 +23,6 @@ import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.ScriptContextTester;

// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: ParameterNumberCheck

/**
* <p>The <code>GlyphPositioningSubtable</code> implements an abstract base of a glyph subtable,
@@ -90,8 +88,8 @@ public abstract class GlyphPositioningSubtable extends GlyphSubtable implements
boolean appliedOneShot = false;
while (ps.hasNext()) {
boolean applied = false;
if (! appliedOneShot && ps.maybeApplicable()) {
for (int i = 0, n = sta.length; ! applied && (i < n); i++) {
if (!appliedOneShot && ps.maybeApplicable()) {
for (int i = 0, n = sta.length; !applied && (i < n); i++) {
if (sequenceIndex < 0) {
applied = ps.apply(sta [ i ]);
} else if (ps.getPosition() == (sequenceStart + sequenceIndex)) {
@@ -102,7 +100,7 @@ public abstract class GlyphPositioningSubtable extends GlyphSubtable implements
}
}
}
if (! applied || ! ps.didConsume()) {
if (!applied || !ps.didConsume()) {
ps.applyDefault();
}
ps.next();

+ 52
- 55
src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java View File

@@ -33,9 +33,6 @@ import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.GlyphTester;

// CSOFF: LineLengthCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: ParameterNumberCheck

/**
* <p>The <code>GlyphPositioningTable</code> class is a glyph table that implements
@@ -368,7 +365,7 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof Value[])) {
if (((o = entries.get(0)) == null) || !(o instanceof Value[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, single entry must be a Value[], but is: " + ((o != null) ? o.getClass() : null));
} else {
Value[] va = (Value[]) o;
@@ -412,7 +409,7 @@ public class GlyphPositioningTable extends GlyphTable {
int offsetLast = counts[0] + counts[1];
// skip any ignored glyphs prior to first non-ignored glyph
for ( ; offset < offsetLast; ++offset) {
if (! ps.isIgnoredGlyph(offset)) {
if (!ps.isIgnoredGlyph(offset)) {
break;
} else {
ps.consume(1);
@@ -429,7 +426,7 @@ public class GlyphPositioningTable extends GlyphTable {
}
// skip any ignored glyphs prior to second non-ignored glyph
for ( ; offset < offsetLast; ++offset) {
if (! ps.isIgnoredGlyph(offset)) {
if (!ps.isIgnoredGlyph(offset)) {
break;
} else {
ps.consume(1);
@@ -513,7 +510,7 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof PairValues[][])) {
if (((o = entries.get(0)) == null) || !(o instanceof PairValues[][])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first (and only) entry must be a PairValues[][], but is: " + ((o != null) ? o.getClass() : null));
} else {
pvm = (PairValues[][]) o;
@@ -569,27 +566,27 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 5 entries");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(0)) == null) || !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an GlyphClassTable, but is: " + ((o != null) ? o.getClass() : null));
} else {
cdt1 = (GlyphClassTable) o;
}
if (((o = entries.get(1)) == null) || ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(1)) == null) || !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, second entry must be an GlyphClassTable, but is: " + ((o != null) ? o.getClass() : null));
} else {
cdt2 = (GlyphClassTable) o;
}
if (((o = entries.get(2)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(2)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, third entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
nc1 = ((Integer)(o)).intValue();
}
if (((o = entries.get(3)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(3)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, fourth entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
nc2 = ((Integer)(o)).intValue();
}
if (((o = entries.get(4)) == null) || ! (o instanceof PairValues[][])) {
if (((o = entries.get(4)) == null) || !(o instanceof PairValues[][])) {
throw new AdvancedTypographicTableFormatException("illegal entries, fifth entry must be a PairValues[][], but is: " + ((o != null) ? o.getClass() : null));
} else {
pvm = (PairValues[][]) o;
@@ -633,7 +630,7 @@ public class GlyphPositioningTable extends GlyphTable {
int enw = ps.getWidth(gi2);
if ((exa != null) && (ena != null)) {
Value v = ena.getAlignmentAdjustment(exa);
v.adjust(- enw, 0, 0, 0);
v.adjust(-enw, 0, 0, 0);
if (ps.adjust(v)) {
ps.setAdjusted(true);
}
@@ -704,10 +701,10 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof Anchor[])) {
if (((o = entries.get(0)) == null) || !(o instanceof Anchor[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first (and only) entry must be a Anchor[], but is: " + ((o != null) ? o.getClass() : null));
} else if ((((Anchor[]) o) . length % 2) != 0) {
throw new AdvancedTypographicTableFormatException("illegal entries, Anchor[] array must have an even number of entries, but has: " + ((Anchor[]) o) . length);
} else if ((((Anchor[]) o) .length % 2) != 0) {
throw new AdvancedTypographicTableFormatException("illegal entries, Anchor[] array must have an even number of entries, but has: " + ((Anchor[]) o) .length);
} else {
aa = (Anchor[]) o;
}
@@ -736,7 +733,7 @@ public class GlyphPositioningTable extends GlyphTable {
MarkAnchor ma = getMarkAnchor(ciMark, giMark);
if (ma != null) {
for (int i = 0, n = ps.getPosition(); i < n; i++) {
int gi = ps.getGlyph(- (i + 1));
int gi = ps.getGlyph(-(i + 1));
if (ps.isMark(gi)) {
continue;
} else {
@@ -746,7 +743,7 @@ public class GlyphPositioningTable extends GlyphTable {
// start experimental fix for END OF AYAH in Lateef/Scheherazade
int[] aa = ps.getAdjustment();
if (aa[2] == 0) {
v.adjust(0, 0, - ps.getWidth(giMark), 0);
v.adjust(0, 0, -ps.getWidth(giMark), 0);
}
// end experimental fix for END OF AYAH in Lateef/Scheherazade
if (ps.adjust(v)) {
@@ -835,22 +832,22 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 4 entries");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof GlyphCoverageTable)) {
if (((o = entries.get(0)) == null) || !(o instanceof GlyphCoverageTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an GlyphCoverageTable, but is: " + ((o != null) ? o.getClass() : null));
} else {
bct = (GlyphCoverageTable) o;
}
if (((o = entries.get(1)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(1)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, second entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
nmc = ((Integer)(o)).intValue();
}
if (((o = entries.get(2)) == null) || ! (o instanceof MarkAnchor[])) {
if (((o = entries.get(2)) == null) || !(o instanceof MarkAnchor[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, third entry must be a MarkAnchor[], but is: " + ((o != null) ? o.getClass() : null));
} else {
maa = (MarkAnchor[]) o;
}
if (((o = entries.get(3)) == null) || ! (o instanceof Anchor[][])) {
if (((o = entries.get(3)) == null) || !(o instanceof Anchor[][])) {
throw new AdvancedTypographicTableFormatException("illegal entries, fourth entry must be a Anchor[][], but is: " + ((o != null) ? o.getClass() : null));
} else {
bam = (Anchor[][]) o;
@@ -881,7 +878,7 @@ public class GlyphPositioningTable extends GlyphTable {
int mxc = getMaxComponentCount();
if (ma != null) {
for (int i = 0, n = ps.getPosition(); i < n; i++) {
int gi = ps.getGlyph(- (i + 1));
int gi = ps.getGlyph(-(i + 1));
if (ps.isMark(gi)) {
continue;
} else {
@@ -989,27 +986,27 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 5 entries");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof GlyphCoverageTable)) {
if (((o = entries.get(0)) == null) || !(o instanceof GlyphCoverageTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an GlyphCoverageTable, but is: " + ((o != null) ? o.getClass() : null));
} else {
lct = (GlyphCoverageTable) o;
}
if (((o = entries.get(1)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(1)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, second entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
nmc = ((Integer)(o)).intValue();
}
if (((o = entries.get(2)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(2)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, third entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
mxc = ((Integer)(o)).intValue();
}
if (((o = entries.get(3)) == null) || ! (o instanceof MarkAnchor[])) {
if (((o = entries.get(3)) == null) || !(o instanceof MarkAnchor[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, fourth entry must be a MarkAnchor[], but is: " + ((o != null) ? o.getClass() : null));
} else {
maa = (MarkAnchor[]) o;
}
if (((o = entries.get(4)) == null) || ! (o instanceof Anchor[][][])) {
if (((o = entries.get(4)) == null) || !(o instanceof Anchor[][][])) {
throw new AdvancedTypographicTableFormatException("illegal entries, fifth entry must be a Anchor[][][], but is: " + ((o != null) ? o.getClass() : null));
} else {
lam = (Anchor[][][]) o;
@@ -1125,22 +1122,22 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 4 entries");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof GlyphCoverageTable)) {
if (((o = entries.get(0)) == null) || !(o instanceof GlyphCoverageTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an GlyphCoverageTable, but is: " + ((o != null) ? o.getClass() : null));
} else {
mct2 = (GlyphCoverageTable) o;
}
if (((o = entries.get(1)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(1)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, second entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
nmc = ((Integer)(o)).intValue();
}
if (((o = entries.get(2)) == null) || ! (o instanceof MarkAnchor[])) {
if (((o = entries.get(2)) == null) || !(o instanceof MarkAnchor[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, third entry must be a MarkAnchor[], but is: " + ((o != null) ? o.getClass() : null));
} else {
maa = (MarkAnchor[]) o;
}
if (((o = entries.get(3)) == null) || ! (o instanceof Anchor[][])) {
if (((o = entries.get(3)) == null) || !(o instanceof Anchor[][])) {
throw new AdvancedTypographicTableFormatException("illegal entries, fourth entry must be a Anchor[][], but is: " + ((o != null) ? o.getClass() : null));
} else {
mam = (Anchor[][]) o;
@@ -1274,7 +1271,7 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(0)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -1367,17 +1364,17 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 3 entries");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(0)) == null) || !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an GlyphClassTable, but is: " + ((o != null) ? o.getClass() : null));
} else {
cdt = (GlyphClassTable) o;
}
if (((o = entries.get(1)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(1)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, second entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
ngc = ((Integer)(o)).intValue();
}
if (((o = entries.get(2)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(2)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, third entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -1467,7 +1464,7 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(0)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -1585,7 +1582,7 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(0)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -1661,27 +1658,27 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 5 entries");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(0)) == null) || !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an GlyphClassTable, but is: " + ((o != null) ? o.getClass() : null));
} else {
icdt = (GlyphClassTable) o;
}
if (((o = entries.get(1)) != null) && ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(1)) != null) && !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, second entry must be an GlyphClassTable, but is: " + o.getClass());
} else {
bcdt = (GlyphClassTable) o;
}
if (((o = entries.get(2)) != null) && ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(2)) != null) && !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, third entry must be an GlyphClassTable, but is: " + o.getClass());
} else {
lcdt = (GlyphClassTable) o;
}
if (((o = entries.get(3)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(3)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, fourth entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
ngc = ((Integer)(o)).intValue();
}
if (((o = entries.get(4)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(4)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, fifth entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -1752,7 +1749,7 @@ public class GlyphPositioningTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(0)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -2005,7 +2002,7 @@ public class GlyphPositioningTable extends GlyphTable {
boolean first = true;
sb.append("{ ");
if (xPlacement != 0) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2013,7 +2010,7 @@ public class GlyphPositioningTable extends GlyphTable {
sb.append("xPlacement = " + xPlacement);
}
if (yPlacement != 0) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2021,7 +2018,7 @@ public class GlyphPositioningTable extends GlyphTable {
sb.append("yPlacement = " + yPlacement);
}
if (xAdvance != 0) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2029,7 +2026,7 @@ public class GlyphPositioningTable extends GlyphTable {
sb.append("xAdvance = " + xAdvance);
}
if (yAdvance != 0) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2037,7 +2034,7 @@ public class GlyphPositioningTable extends GlyphTable {
sb.append("yAdvance = " + yAdvance);
}
if (xPlaDevice != null) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2045,7 +2042,7 @@ public class GlyphPositioningTable extends GlyphTable {
sb.append("xPlaDevice = " + xPlaDevice);
}
if (yPlaDevice != null) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2053,7 +2050,7 @@ public class GlyphPositioningTable extends GlyphTable {
sb.append("xPlaDevice = " + yPlaDevice);
}
if (xAdvDevice != null) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2061,7 +2058,7 @@ public class GlyphPositioningTable extends GlyphTable {
sb.append("xAdvDevice = " + xAdvDevice);
}
if (yAdvDevice != null) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2118,7 +2115,7 @@ public class GlyphPositioningTable extends GlyphTable {
boolean first = true;
sb.append("{ ");
if (glyph != 0) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2126,7 +2123,7 @@ public class GlyphPositioningTable extends GlyphTable {
sb.append("glyph = " + glyph);
}
if (value1 != null) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;
@@ -2134,7 +2131,7 @@ public class GlyphPositioningTable extends GlyphTable {
sb.append("value1 = " + value1);
}
if (value2 != null) {
if (! first) {
if (!first) {
sb.append(", ");
} else {
first = false;

+ 10
- 11
src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java View File

@@ -29,7 +29,6 @@ import org.apache.fop.complexscripts.util.GlyphTester;
import org.apache.fop.complexscripts.util.ScriptContextTester;

// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck

/**
* <p>The <code>GlyphProcessingState</code> implements a common, base state object used during glyph substitution
@@ -459,7 +458,7 @@ public class GlyphProcessingState {
int start = index + offset;
if (start < 0) {
throw new IndexOutOfBoundsException("will attempt index at " + start);
} else if (! reverseOrder && ((start + count) > indexLast)) {
} else if (!reverseOrder && ((start + count) > indexLast)) {
throw new IndexOutOfBoundsException("will attempt index at " + (start + count));
} else if (reverseOrder && ((start + 1) < count)) {
throw new IndexOutOfBoundsException("will attempt index at " + (start - count));
@@ -469,7 +468,7 @@ public class GlyphProcessingState {
} else if (glyphs.length != count) {
throw new IllegalArgumentException("glyphs array is non-null, but its length (" + glyphs.length + "), is not equal to count (" + count + ")");
}
if (! reverseOrder) {
if (!reverseOrder) {
return getGlyphsForward(start, count, ignoreTester, glyphs, counts);
} else {
return getGlyphsReverse(start, count, ignoreTester, glyphs, counts);
@@ -484,7 +483,7 @@ public class GlyphProcessingState {
if (gi == 65535) {
ignored++;
} else {
if ((ignoreTester == null) || ! ignoreTester.test(gi, getLookupFlags())) {
if ((ignoreTester == null) || !ignoreTester.test(gi, getLookupFlags())) {
glyphs [ counted++ ] = gi;
} else {
ignored++;
@@ -506,7 +505,7 @@ public class GlyphProcessingState {
if (gi == 65535) {
ignored++;
} else {
if ((ignoreTester == null) || ! ignoreTester.test(gi, getLookupFlags())) {
if ((ignoreTester == null) || !ignoreTester.test(gi, getLookupFlags())) {
glyphs [ counted++ ] = gi;
} else {
ignored++;
@@ -629,7 +628,7 @@ public class GlyphProcessingState {
int start = index + offset;
if ((start < 0) || (start > indexLast)) {
return new int[] { 0, 0 };
} else if (! reverseOrder) {
} else if (!reverseOrder) {
return getGlyphsAvailableForward(start, ignoreTester);
} else {
return getGlyphsAvailableReverse(start, ignoreTester);
@@ -731,7 +730,7 @@ public class GlyphProcessingState {
int start = index + offset;
if (start < 0) {
throw new IndexOutOfBoundsException("will attempt index at " + start);
} else if (! reverseOrder && ((start + count) > indexLast)) {
} else if (!reverseOrder && ((start + count) > indexLast)) {
throw new IndexOutOfBoundsException("will attempt index at " + (start + count));
} else if (reverseOrder && ((start + 1) < count)) {
throw new IndexOutOfBoundsException("will attempt index at " + (start - count));
@@ -741,7 +740,7 @@ public class GlyphProcessingState {
} else if (associations.length != count) {
throw new IllegalArgumentException("associations array is non-null, but its length (" + associations.length + "), is not equal to count (" + count + ")");
}
if (! reverseOrder) {
if (!reverseOrder) {
return getAssociationsForward(start, count, ignoreTester, associations, counts);
} else {
return getAssociationsReverse(start, count, ignoreTester, associations, counts);
@@ -757,7 +756,7 @@ public class GlyphProcessingState {
if (gi == 65535) {
ignored++;
} else {
if ((ignoreTester == null) || ! ignoreTester.test(gi, getLookupFlags())) {
if ((ignoreTester == null) || !ignoreTester.test(gi, getLookupFlags())) {
if (k < count) {
associations [ k++ ] = getAssociation(i - index);
counted++;
@@ -785,7 +784,7 @@ public class GlyphProcessingState {
if (gi == 65535) {
ignored++;
} else {
if ((ignoreTester == null) || ! ignoreTester.test(gi, getLookupFlags())) {
if ((ignoreTester == null) || !ignoreTester.test(gi, getLookupFlags())) {
if (k < count) {
associations [ k++ ] = getAssociation(i - index);
counted++;
@@ -1169,7 +1168,7 @@ public class GlyphProcessingState {
for (int i = 0, n = ngt; i < n; i++) {
GlyphTester gt = gta [ i ];
if (gt != null) {
if (! gt.test(gi, flags)) {
if (!gt.test(gi, flags)) {
return false;
}
}

+ 1
- 2
src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionState.java View File

@@ -27,7 +27,6 @@ import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.ScriptContextTester;

// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck

/**
* <p>The <code>GlyphSubstitutionState</code> implements an state object used during glyph substitution
@@ -130,7 +129,7 @@ public class GlyphSubstitutionState extends GlyphProcessingState {
* @param predication a predication value to add to association A if predications enabled
*/
public void putGlyph(int glyph, GlyphSequence.CharAssociation a, Object predication) {
if (! ogb.hasRemaining()) {
if (!ogb.hasRemaining()) {
ogb = growBuffer(ogb);
}
ogb.put(glyph);

+ 3
- 4
src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionSubtable.java View File

@@ -23,7 +23,6 @@ import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.ScriptContextTester;

// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck

/**
* <p>The <code>GlyphSubstitutionSubtable</code> implements an abstract base of a glyph substitution subtable,
@@ -90,8 +89,8 @@ public abstract class GlyphSubstitutionSubtable extends GlyphSubtable implements
boolean appliedOneShot = false;
while (ss.hasNext()) {
boolean applied = false;
if (! appliedOneShot && ss.maybeApplicable()) {
for (int i = 0, n = sta.length; ! applied && (i < n); i++) {
if (!appliedOneShot && ss.maybeApplicable()) {
for (int i = 0, n = sta.length; !applied && (i < n); i++) {
if (sequenceIndex < 0) {
applied = ss.apply(sta [ i ]);
} else if (ss.getPosition() == (sequenceStart + sequenceIndex)) {
@@ -102,7 +101,7 @@ public abstract class GlyphSubstitutionSubtable extends GlyphSubtable implements
}
}
}
if (! applied || ! ss.didConsume()) {
if (!applied || !ss.didConsume()) {
ss.applyDefault();
}
ss.next();

+ 14
- 16
src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionTable.java View File

@@ -31,9 +31,7 @@ import org.apache.fop.complexscripts.scripts.ScriptProcessor;
import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.GlyphTester;

// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck

/**
* <p>The <code>GlyphSubstitutionTable</code> class is a glyph table that implements
@@ -306,7 +304,7 @@ public class GlyphSubstitutionTable extends GlyphTable {
Object o = entries.get(0);
int delta = 0;
if (o instanceof Integer) {
delta = ((Integer) o) . intValue();
delta = ((Integer) o) .intValue();
} else {
throw new AdvancedTypographicTableFormatException("illegal entries entry, must be Integer, but is: " + o);
}
@@ -440,7 +438,7 @@ public class GlyphSubstitutionTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof int[][])) {
if (((o = entries.get(0)) == null) || !(o instanceof int[][])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an int[][], but is: " + ((o != null) ? o.getClass() : null));
} else {
gsa = (int[][]) o;
@@ -801,7 +799,7 @@ public class GlyphSubstitutionTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(0)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -894,17 +892,17 @@ public class GlyphSubstitutionTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 3 entries");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(0)) == null) || !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an GlyphClassTable, but is: " + ((o != null) ? o.getClass() : null));
} else {
cdt = (GlyphClassTable) o;
}
if (((o = entries.get(1)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(1)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, second entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
ngc = ((Integer)(o)).intValue();
}
if (((o = entries.get(2)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(2)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, third entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -994,7 +992,7 @@ public class GlyphSubstitutionTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(0)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -1113,7 +1111,7 @@ public class GlyphSubstitutionTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(0)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -1189,27 +1187,27 @@ public class GlyphSubstitutionTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 5 entries");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(0)) == null) || !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an GlyphClassTable, but is: " + ((o != null) ? o.getClass() : null));
} else {
icdt = (GlyphClassTable) o;
}
if (((o = entries.get(1)) != null) && ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(1)) != null) && !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, second entry must be an GlyphClassTable, but is: " + o.getClass());
} else {
bcdt = (GlyphClassTable) o;
}
if (((o = entries.get(2)) != null) && ! (o instanceof GlyphClassTable)) {
if (((o = entries.get(2)) != null) && !(o instanceof GlyphClassTable)) {
throw new AdvancedTypographicTableFormatException("illegal entries, third entry must be an GlyphClassTable, but is: " + o.getClass());
} else {
lcdt = (GlyphClassTable) o;
}
if (((o = entries.get(3)) == null) || ! (o instanceof Integer)) {
if (((o = entries.get(3)) == null) || !(o instanceof Integer)) {
throw new AdvancedTypographicTableFormatException("illegal entries, fourth entry must be an Integer, but is: " + ((o != null) ? o.getClass() : null));
} else {
ngc = ((Integer)(o)).intValue();
}
if (((o = entries.get(4)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(4)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, fifth entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;
@@ -1280,7 +1278,7 @@ public class GlyphSubstitutionTable extends GlyphTable {
throw new AdvancedTypographicTableFormatException("illegal entries, " + entries.size() + " entries present, but requires 1 entry");
} else {
Object o;
if (((o = entries.get(0)) == null) || ! (o instanceof RuleSet[])) {
if (((o = entries.get(0)) == null) || !(o instanceof RuleSet[])) {
throw new AdvancedTypographicTableFormatException("illegal entries, first entry must be an RuleSet[], but is: " + ((o != null) ? o.getClass() : null));
} else {
rsa = (RuleSet[]) o;

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

@@ -24,7 +24,6 @@ import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Map;

// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck

/**

+ 21
- 28
src/java/org/apache/fop/complexscripts/fonts/GlyphTable.java View File

@@ -37,12 +37,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.ScriptContextTester;

// CSOFF: EmptyForIteratorPadCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: ParameterNumberCheck
// CSOFF: SimplifyBooleanReturnCheck

/**
* <p>Base class for all advanced typographic glyph tables.</p>
@@ -86,7 +81,7 @@ public class GlyphTable {
* @param lookups map from lookup specs to lookup tables
*/
public GlyphTable(GlyphTable gdef, Map/*<LookupSpec,List<String>>*/ lookups) {
if ((gdef != null) && ! (gdef instanceof GlyphDefinitionTable)) {
if ((gdef != null) && !(gdef instanceof GlyphDefinitionTable)) {
throw new AdvancedTypographicTableFormatException("bad glyph definition table");
} else if (lookups == null) {
throw new AdvancedTypographicTableFormatException("lookups must be non-null map");
@@ -166,7 +161,7 @@ public class GlyphTable {
* create resulting cached state.
*/
protected void freezeSubtables() {
if (! frozen) {
if (!frozen) {
for (Iterator it = lookupTables.values().iterator(); it.hasNext(); ) {
LookupTable lt = (LookupTable) it.next();
lt.freezeSubtables(lookupTables);
@@ -188,18 +183,18 @@ public class GlyphTable {
List/*<LookupSpec>*/ matches = new ArrayList/*<LookupSpec>*/();
for (Iterator it = keys.iterator(); it.hasNext();) {
LookupSpec ls = (LookupSpec) it.next();
if (! "*".equals(script)) {
if (! ls.getScript().equals(script)) {
if (!"*".equals(script)) {
if (!ls.getScript().equals(script)) {
continue;
}
}
if (! "*".equals(language)) {
if (! ls.getLanguage().equals(language)) {
if (!"*".equals(language)) {
if (!ls.getLanguage().equals(language)) {
continue;
}
}
if (! "*".equals(feature)) {
if (! ls.getFeature().equals(feature)) {
if (!"*".equals(feature)) {
if (!ls.getFeature().equals(feature)) {
continue;
}
}
@@ -359,17 +354,17 @@ public class GlyphTable {
* @param permitWildcard if true the permit wildcard script, language, or feature
*/
LookupSpec(String script, String language, String feature, boolean permitEmpty, boolean permitWildcard) {
if ((script == null) || (! permitEmpty && (script.length() == 0))) {
if ((script == null) || (!permitEmpty && (script.length() == 0))) {
throw new AdvancedTypographicTableFormatException("script must be non-empty string");
} else if ((language == null) || (! permitEmpty && (language.length() == 0))) {
} else if ((language == null) || (!permitEmpty && (language.length() == 0))) {
throw new AdvancedTypographicTableFormatException("language must be non-empty string");
} else if ((feature == null) || (! permitEmpty && (feature.length() == 0))) {
} else if ((feature == null) || (!permitEmpty && (feature.length() == 0))) {
throw new AdvancedTypographicTableFormatException("feature must be non-empty string");
} else if (! permitWildcard && script.equals("*")) {
} else if (!permitWildcard && script.equals("*")) {
throw new AdvancedTypographicTableFormatException("script must not be wildcard");
} else if (! permitWildcard && language.equals("*")) {
} else if (!permitWildcard && language.equals("*")) {
throw new AdvancedTypographicTableFormatException("language must not be wildcard");
} else if (! permitWildcard && feature.equals("*")) {
} else if (!permitWildcard && feature.equals("*")) {
throw new AdvancedTypographicTableFormatException("feature must not be wildcard");
}
this.script = script.trim();
@@ -405,14 +400,12 @@ public class GlyphTable {
public boolean equals(Object o) {
if (o instanceof LookupSpec) {
LookupSpec l = (LookupSpec) o;
if (! l.script.equals(script)) {
if (!l.script.equals(script)) {
return false;
} else if (! l.language.equals(language)) {
return false;
} else if (! l.feature.equals(feature)) {
} else if (!l.language.equals(language)) {
return false;
} else {
return true;
return l.feature.equals(feature);
}
} else {
return false;
@@ -540,7 +533,7 @@ public class GlyphTable {
}
}
// append at end of list
if (! added && (subtable != null)) {
if (!added && (subtable != null)) {
subtables.add(subtable);
added = true;
}
@@ -567,7 +560,7 @@ public class GlyphTable {
}
if (subtables.size() > 0) {
GlyphSubtable st = (GlyphSubtable) subtables.get(0);
if (! st.isCompatible(subtable)) {
if (!st.isCompatible(subtable)) {
throw new AdvancedTypographicTableFormatException("subtable " + subtable + " is not compatible with subtable " + st);
}
}
@@ -580,7 +573,7 @@ public class GlyphTable {
* @param lookupTables map from lookup table identifers, e.g. "lu4", to lookup tables
*/
public void freezeSubtables(Map/*<String,LookupTable>*/ lookupTables) {
if (! frozen) {
if (!frozen) {
GlyphSubtable[] sta = getSubtables();
resolveLookupReferences(sta, lookupTables);
this.subtablesArray = sta;
@@ -1305,7 +1298,7 @@ public class GlyphTable {
Class c = r0.getClass();
for (int i = 1, n = rules.length; i < n; i++) {
Rule r = rules[i];
if ((r != null) && ! c.isInstance(r)) {
if ((r != null) && !c.isInstance(r)) {
throw new AdvancedTypographicTableFormatException("rules[" + i + "] is not an instance of " + c.getName());
}
}

+ 45
- 48
src/java/org/apache/fop/complexscripts/fonts/OTFAdvancedTypographicTableReader.java View File

@@ -29,14 +29,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.fonts.truetype.FontFileReader;
import org.apache.fop.fonts.truetype.TTFDirTabEntry;
import org.apache.fop.fonts.truetype.TTFFile;
import org.apache.fop.fonts.truetype.TTFTableName;

// CSOFF: AvoidNestedBlocksCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: SimplifyBooleanReturnCheck
import org.apache.fop.fonts.truetype.OFDirTabEntry;
import org.apache.fop.fonts.truetype.OFTableName;
import org.apache.fop.fonts.truetype.OpenFont;

// CSOFF: LineLengthCheck

/**
@@ -50,7 +46,7 @@ public final class OTFAdvancedTypographicTableReader {
// logging state
private static Log log = LogFactory.getLog(OTFAdvancedTypographicTableReader.class);
// instance state
private TTFFile ttf; // parent font file reader
private OpenFont otf; // parent font file reader
private FontFileReader in; // input reader
private GlyphDefinitionTable gdef; // glyph definition table
private GlyphSubstitutionTable gsub; // glyph substitution table
@@ -68,10 +64,10 @@ public final class OTFAdvancedTypographicTableReader {
* @param ttf parent font file reader (must be non-null)
* @param in font file reader (must be non-null)
*/
public OTFAdvancedTypographicTableReader(TTFFile ttf, FontFileReader in) {
assert ttf != null;
public OTFAdvancedTypographicTableReader(OpenFont otf, FontFileReader in) {
assert otf != null;
assert in != null;
this.ttf = ttf;
this.otf = otf;
this.in = in;
}

@@ -127,7 +123,8 @@ public final class OTFAdvancedTypographicTableReader {
return gpos;
}

private void readLangSysTable(TTFTableName tableTag, long langSysTable, String langSysTag) throws IOException {
private void readLangSysTable(OFTableName tableTag, long langSysTable, String langSysTag)
throws IOException {
in.seekSet(langSysTable);
if (log.isDebugEnabled()) {
log.debug(tableTag + " lang sys table: " + langSysTag);
@@ -169,7 +166,7 @@ public final class OTFAdvancedTypographicTableReader {

private static String defaultTag = "dflt";

private void readScriptTable(TTFTableName tableTag, long scriptTable, String scriptTag) throws IOException {
private void readScriptTable(OFTableName tableTag, long scriptTable, String scriptTag) throws IOException {
in.seekSet(scriptTable);
if (log.isDebugEnabled()) {
log.debug(tableTag + " script table: " + scriptTag);
@@ -222,7 +219,7 @@ public final class OTFAdvancedTypographicTableReader {
seLanguages = null;
}

private void readScriptList(TTFTableName tableTag, long scriptList) throws IOException {
private void readScriptList(OFTableName tableTag, long scriptList) throws IOException {
in.seekSet(scriptList);
// read script record count
int ns = in.readTTFUShort();
@@ -251,7 +248,7 @@ public final class OTFAdvancedTypographicTableReader {
}
}

private void readFeatureTable(TTFTableName tableTag, long featureTable, String featureTag, int featureIndex) throws IOException {
private void readFeatureTable(OFTableName tableTag, long featureTable, String featureTag, int featureIndex) throws IOException {
in.seekSet(featureTable);
if (log.isDebugEnabled()) {
log.debug(tableTag + " feature table: " + featureTag);
@@ -279,7 +276,7 @@ public final class OTFAdvancedTypographicTableReader {
seFeatures.put("f" + featureIndex, new Object[] { featureTag, lul });
}

private void readFeatureList(TTFTableName tableTag, long featureList) throws IOException {
private void readFeatureList(OFTableName tableTag, long featureList) throws IOException {
in.seekSet(featureList);
// read feature record count
int nf = in.readTTFUShort();
@@ -1736,28 +1733,28 @@ public final class OTFAdvancedTypographicTableReader {
// XPlacement
int xp;
if ((valueFormat & GlyphPositioningTable.Value.X_PLACEMENT) != 0) {
xp = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
xp = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
} else {
xp = 0;
}
// YPlacement
int yp;
if ((valueFormat & GlyphPositioningTable.Value.Y_PLACEMENT) != 0) {
yp = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
yp = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
} else {
yp = 0;
}
// XAdvance
int xa;
if ((valueFormat & GlyphPositioningTable.Value.X_ADVANCE) != 0) {
xa = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
xa = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
} else {
xa = 0;
}
// YAdvance
int ya;
if ((valueFormat & GlyphPositioningTable.Value.Y_ADVANCE) != 0) {
ya = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
ya = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
} else {
ya = 0;
}
@@ -2029,23 +2026,23 @@ public final class OTFAdvancedTypographicTableReader {
int af = in.readTTFUShort();
if (af == 1) {
// read x coordinate
int x = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
int x = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
// read y coordinate
int y = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
int y = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
a = new GlyphPositioningTable.Anchor(x, y);
} else if (af == 2) {
// read x coordinate
int x = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
int x = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
// read y coordinate
int y = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
int y = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
// read anchor point index
int ap = in.readTTFUShort();
a = new GlyphPositioningTable.Anchor(x, y, ap);
} else if (af == 3) {
// read x coordinate
int x = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
int x = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
// read y coordinate
int y = ttf.convertTTFUnit2PDFUnit(in.readTTFShort());
int y = otf.convertTTFUnit2PDFUnit(in.readTTFShort());
// read x device table offset
int xdo = in.readTTFUShort();
// read y device table offset
@@ -3145,9 +3142,9 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}

private void readLookupTable(TTFTableName tableTag, int lookupSequence, long lookupTable) throws IOException {
boolean isGSUB = tableTag.equals(TTFTableName.GSUB);
boolean isGPOS = tableTag.equals(TTFTableName.GPOS);
private void readLookupTable(OFTableName tableTag, int lookupSequence, long lookupTable) throws IOException {
boolean isGSUB = tableTag.equals(OFTableName.GSUB);
boolean isGPOS = tableTag.equals(OFTableName.GPOS);
in.seekSet(lookupTable);
// read lookup type
int lt = in.readTTFUShort();
@@ -3198,7 +3195,7 @@ public final class OTFAdvancedTypographicTableReader {
}
}

private void readLookupList(TTFTableName tableTag, long lookupList) throws IOException {
private void readLookupList(OFTableName tableTag, long lookupList) throws IOException {
in.seekSet(lookupList);
// read lookup record count
int nl = in.readTTFUShort();
@@ -3233,7 +3230,7 @@ public final class OTFAdvancedTypographicTableReader {
* @param lookupList offset to lookup list from beginning of font file
* @throws IOException In case of a I/O problem
*/
private void readCommonLayoutTables(TTFTableName tableTag, long scriptList, long featureList, long lookupList) throws IOException {
private void readCommonLayoutTables(OFTableName tableTag, long scriptList, long featureList, long lookupList) throws IOException {
if (scriptList > 0) {
readScriptList(tableTag, scriptList);
}
@@ -3245,7 +3242,7 @@ public final class OTFAdvancedTypographicTableReader {
}
}

private void readGDEFClassDefTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
private void readGDEFClassDefTable(OFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// subtable is a bare class definition table
@@ -3257,7 +3254,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}

private void readGDEFAttachmentTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
private void readGDEFAttachmentTable(OFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// read coverage offset
@@ -3275,7 +3272,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}

private void readGDEFLigatureCaretTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
private void readGDEFLigatureCaretTable(OFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// read coverage offset
@@ -3305,7 +3302,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}

private void readGDEFMarkAttachmentTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
private void readGDEFMarkAttachmentTable(OFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// subtable is a bare class definition table
@@ -3317,7 +3314,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}

private void readGDEFMarkGlyphsTableFormat1(TTFTableName tableTag, int lookupSequence, long subtableOffset, int subtableFormat) throws IOException {
private void readGDEFMarkGlyphsTableFormat1(OFTableName tableTag, int lookupSequence, long subtableOffset, int subtableFormat) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// skip over format (already known)
@@ -3351,7 +3348,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}

private void readGDEFMarkGlyphsTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
private void readGDEFMarkGlyphsTable(OFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
in.seekSet(subtableOffset);
// read mark set subtable format
int sf = in.readTTFUShort();
@@ -3367,17 +3364,17 @@ public final class OTFAdvancedTypographicTableReader {
* @throws IOException In case of a I/O problem
*/
private void readGDEF() throws IOException {
TTFTableName tableTag = TTFTableName.GDEF;
OFTableName tableTag = OFTableName.GDEF;
// Initialize temporary state
initATState();
// Read glyph definition (GDEF) table
TTFDirTabEntry dirTab = ttf.getDirectoryEntry(tableTag);
OFDirTabEntry dirTab = otf.getDirectoryEntry(tableTag);
if (gdef != null) {
if (log.isDebugEnabled()) {
log.debug(tableTag + ": ignoring duplicate table");
}
} else if (dirTab != null) {
ttf.seekTab(in, tableTag, 0);
otf.seekTab(in, tableTag, 0);
long version = in.readTTFULong();
if (log.isDebugEnabled()) {
log.debug(tableTag + " version: " + (version / 65536) + "." + (version % 65536));
@@ -3440,17 +3437,17 @@ public final class OTFAdvancedTypographicTableReader {
* @throws IOException In case of a I/O problem
*/
private void readGSUB() throws IOException {
TTFTableName tableTag = TTFTableName.GSUB;
OFTableName tableTag = OFTableName.GSUB;
// Initialize temporary state
initATState();
// Read glyph substitution (GSUB) table
TTFDirTabEntry dirTab = ttf.getDirectoryEntry(tableTag);
OFDirTabEntry dirTab = otf.getDirectoryEntry(tableTag);
if (gpos != null) {
if (log.isDebugEnabled()) {
log.debug(tableTag + ": ignoring duplicate table");
}
} else if (dirTab != null) {
ttf.seekTab(in, tableTag, 0);
otf.seekTab(in, tableTag, 0);
int version = in.readTTFLong();
if (log.isDebugEnabled()) {
log.debug(tableTag + " version: " + (version / 65536) + "." + (version % 65536));
@@ -3477,17 +3474,17 @@ public final class OTFAdvancedTypographicTableReader {
* @throws IOException In case of a I/O problem
*/
private void readGPOS() throws IOException {
TTFTableName tableTag = TTFTableName.GPOS;
OFTableName tableTag = OFTableName.GPOS;
// Initialize temporary state
initATState();
// Read glyph positioning (GPOS) table
TTFDirTabEntry dirTab = ttf.getDirectoryEntry(tableTag);
OFDirTabEntry dirTab = otf.getDirectoryEntry(tableTag);
if (gpos != null) {
if (log.isDebugEnabled()) {
log.debug(tableTag + ": ignoring duplicate table");
}
} else if (dirTab != null) {
ttf.seekTab(in, tableTag, 0);
otf.seekTab(in, tableTag, 0);
int version = in.readTTFLong();
if (log.isDebugEnabled()) {
log.debug(tableTag + " version: " + (version / 65536) + "." + (version % 65536));
@@ -3790,7 +3787,7 @@ public final class OTFAdvancedTypographicTableReader {
} else {
boolean first = true;
for (int i = 0; i < ia.length; i++) {
if (! first) {
if (!first) {
sb.append(' ');
} else {
first = false;

+ 9
- 13
src/java/org/apache/fop/complexscripts/scripts/ArabicScriptProcessor.java View File

@@ -33,10 +33,6 @@ import org.apache.fop.complexscripts.util.GlyphContextTester;
import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.ScriptContextTester;

// CSOFF: AvoidNestedBlocksCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: SimplifyBooleanReturnCheck
// CSOFF: LineLengthCheck

/**
@@ -159,11 +155,11 @@ public class ArabicScriptProcessor extends DefaultScriptProcessor {
} else {
int s = a.getStart();
int e = a.getEnd();
if (! hasFinalPrecedingContext(ca, nc, s, e)) {
if (!hasFinalPrecedingContext(ca, nc, s, e)) {
return false;
} else if (forcesFinalThisContext(ca, nc, s, e)) {
return true;
} else if (! hasFinalFollowingContext(ca, nc, s, e)) {
} else if (!hasFinalFollowingContext(ca, nc, s, e)) {
return false;
} else {
return true;
@@ -180,9 +176,9 @@ public class ArabicScriptProcessor extends DefaultScriptProcessor {
} else {
int s = a.getStart();
int e = a.getEnd();
if (! hasInitialPrecedingContext(ca, nc, s, e)) {
if (!hasInitialPrecedingContext(ca, nc, s, e)) {
return false;
} else if (! hasInitialFollowingContext(ca, nc, s, e)) {
} else if (!hasInitialFollowingContext(ca, nc, s, e)) {
return false;
} else {
return true;
@@ -211,9 +207,9 @@ public class ArabicScriptProcessor extends DefaultScriptProcessor {
} else {
int s = a.getStart();
int e = a.getEnd();
if (! hasLigaturePrecedingContext(ca, nc, s, e)) {
if (!hasLigaturePrecedingContext(ca, nc, s, e)) {
return false;
} else if (! hasLigatureFollowingContext(ca, nc, s, e)) {
} else if (!hasLigatureFollowingContext(ca, nc, s, e)) {
return false;
} else {
return true;
@@ -230,11 +226,11 @@ public class ArabicScriptProcessor extends DefaultScriptProcessor {
} else {
int s = a.getStart();
int e = a.getEnd();
if (! hasMedialPrecedingContext(ca, nc, s, e)) {
if (!hasMedialPrecedingContext(ca, nc, s, e)) {
return false;
} else if (! hasMedialThisContext(ca, nc, s, e)) {
} else if (!hasMedialThisContext(ca, nc, s, e)) {
return false;
} else if (! hasMedialFollowingContext(ca, nc, s, e)) {
} else if (!hasMedialFollowingContext(ca, nc, s, e)) {
return false;
} else {
return true;

+ 11
- 16
src/java/org/apache/fop/complexscripts/scripts/DevanagariScriptProcessor.java View File

@@ -24,11 +24,6 @@ import org.apache.commons.logging.LogFactory;

import org.apache.fop.complexscripts.util.GlyphSequence;

// CSOFF: AvoidNestedBlocksCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: WhitespaceAfter
// CSOFF: InnerAssignmentCheck
// CSOFF: SimplifyBooleanReturnCheck
// CSOFF: LineLengthCheck

/**
@@ -109,7 +104,7 @@ public class DevanagariScriptProcessor extends IndicScriptProcessor {
}

private static boolean containsHalfConsonant(GlyphSequence gs, int k) {
Boolean half = (Boolean) gs.getAssociation(k) . getPredication("half");
Boolean half = (Boolean) gs.getAssociation(k) .getPredication("half");
return (half != null) ? half.booleanValue() : false;
}

@@ -134,7 +129,7 @@ public class DevanagariScriptProcessor extends IndicScriptProcessor {
// first candidate target is after first non-half consonant
for (int i = 0; i < ng; i++) {
if ((i != source) && containsConsonant(gs, i)) {
if (! containsHalfConsonant(gs, i)) {
if (!containsHalfConsonant(gs, i)) {
c1 = i + 1;
break;
}
@@ -142,7 +137,7 @@ public class DevanagariScriptProcessor extends IndicScriptProcessor {
}
// second candidate target is after last non-prebase matra after first candidate or before first syllable or vedic mark
for (int i = (c1 >= 0) ? c1 : 0; i < ng; i++) {
if (containsMatra(gs, i) && ! containsPreBaseMatra(gs, i)) {
if (containsMatra(gs, i) && !containsPreBaseMatra(gs, i)) {
c2 = i + 1;
} else if (containsOtherMark(gs, i)) {
c2 = i;
@@ -159,7 +154,7 @@ public class DevanagariScriptProcessor extends IndicScriptProcessor {
}

private static boolean containsReph(GlyphSequence gs, int k) {
Boolean rphf = (Boolean) gs.getAssociation(k) . getPredication("rphf");
Boolean rphf = (Boolean) gs.getAssociation(k) .getPredication("rphf");
return (rphf != null) ? rphf.booleanValue() : false;
}

@@ -503,13 +498,13 @@ public class DevanagariScriptProcessor extends IndicScriptProcessor {
}
}
static boolean isC(int c) {
return isType(c,C_C);
return isType(c, C_C);
}
static boolean isR(int c) {
return isType(c,C_C) && hasR(c);
return isType(c, C_C) && hasR(c);
}
static boolean isV(int c) {
return isType(c,C_V);
return isType(c, C_V);
}
static boolean isN(int c) {
return c == 0x093C;
@@ -518,10 +513,10 @@ public class DevanagariScriptProcessor extends IndicScriptProcessor {
return c == 0x094D;
}
static boolean isM(int c) {
return isType(c,C_M);
return isType(c, C_M);
}
static boolean isPreM(int c) {
return isType(c,C_M) && hasFlag(c,C_PRE);
return isType(c, C_M) && hasFlag(c, C_PRE);
}
static boolean isX(int c) {
switch (typeOf(c)) {
@@ -535,10 +530,10 @@ public class DevanagariScriptProcessor extends IndicScriptProcessor {
}
}
static boolean hasR(int c) {
return hasFlag(c,C_R);
return hasFlag(c, C_R);
}
static boolean hasN(int c) {
return hasFlag(c,C_N);
return hasFlag(c, C_N);
}

}

+ 11
- 16
src/java/org/apache/fop/complexscripts/scripts/GujaratiScriptProcessor.java View File

@@ -24,11 +24,6 @@ import org.apache.commons.logging.LogFactory;

import org.apache.fop.complexscripts.util.GlyphSequence;

// CSOFF: AvoidNestedBlocksCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: WhitespaceAfter
// CSOFF: InnerAssignmentCheck
// CSOFF: SimplifyBooleanReturnCheck
// CSOFF: LineLengthCheck

/**
@@ -109,7 +104,7 @@ public class GujaratiScriptProcessor extends IndicScriptProcessor {
}

private static boolean containsHalfConsonant(GlyphSequence gs, int k) {
Boolean half = (Boolean) gs.getAssociation(k) . getPredication("half");
Boolean half = (Boolean) gs.getAssociation(k) .getPredication("half");
return (half != null) ? half.booleanValue() : false;
}

@@ -134,7 +129,7 @@ public class GujaratiScriptProcessor extends IndicScriptProcessor {
// first candidate target is after first non-half consonant
for (int i = 0; i < ng; i++) {
if ((i != source) && containsConsonant(gs, i)) {
if (! containsHalfConsonant(gs, i)) {
if (!containsHalfConsonant(gs, i)) {
c1 = i + 1;
break;
}
@@ -142,7 +137,7 @@ public class GujaratiScriptProcessor extends IndicScriptProcessor {
}
// second candidate target is after last non-prebase matra after first candidate or before first syllable or vedic mark
for (int i = (c1 >= 0) ? c1 : 0; i < ng; i++) {
if (containsMatra(gs, i) && ! containsPreBaseMatra(gs, i)) {
if (containsMatra(gs, i) && !containsPreBaseMatra(gs, i)) {
c2 = i + 1;
} else if (containsOtherMark(gs, i)) {
c2 = i;
@@ -159,7 +154,7 @@ public class GujaratiScriptProcessor extends IndicScriptProcessor {
}

private static boolean containsReph(GlyphSequence gs, int k) {
Boolean rphf = (Boolean) gs.getAssociation(k) . getPredication("rphf");
Boolean rphf = (Boolean) gs.getAssociation(k) .getPredication("rphf");
return (rphf != null) ? rphf.booleanValue() : false;
}

@@ -503,13 +498,13 @@ public class GujaratiScriptProcessor extends IndicScriptProcessor {
}
}
static boolean isC(int c) {
return isType(c,C_C);
return isType(c, C_C);
}
static boolean isR(int c) {
return isType(c,C_C) && hasR(c);
return isType(c, C_C) && hasR(c);
}
static boolean isV(int c) {
return isType(c,C_V);
return isType(c, C_V);
}
static boolean isN(int c) {
return c == 0x0ABC;
@@ -518,10 +513,10 @@ public class GujaratiScriptProcessor extends IndicScriptProcessor {
return c == 0x0ACD;
}
static boolean isM(int c) {
return isType(c,C_M);
return isType(c, C_M);
}
static boolean isPreM(int c) {
return isType(c,C_M) && hasFlag(c,C_PRE);
return isType(c, C_M) && hasFlag(c, C_PRE);
}
static boolean isX(int c) {
switch (typeOf(c)) {
@@ -535,10 +530,10 @@ public class GujaratiScriptProcessor extends IndicScriptProcessor {
}
}
static boolean hasR(int c) {
return hasFlag(c,C_R);
return hasFlag(c, C_R);
}
static boolean hasN(int c) {
return hasFlag(c,C_N);
return hasFlag(c, C_N);
}

}

+ 11
- 16
src/java/org/apache/fop/complexscripts/scripts/GurmukhiScriptProcessor.java View File

@@ -25,11 +25,6 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;
import org.apache.fop.complexscripts.util.GlyphSequence;

// CSOFF: AvoidNestedBlocksCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: WhitespaceAfter
// CSOFF: InnerAssignmentCheck
// CSOFF: SimplifyBooleanReturnCheck
// CSOFF: LineLengthCheck

/**
@@ -110,7 +105,7 @@ public class GurmukhiScriptProcessor extends IndicScriptProcessor {
}

private static boolean containsHalfConsonant(GlyphSequence gs, int k) {
Boolean half = (Boolean) gs.getAssociation(k) . getPredication("half");
Boolean half = (Boolean) gs.getAssociation(k) .getPredication("half");
return (half != null) ? half.booleanValue() : false;
}

@@ -135,7 +130,7 @@ public class GurmukhiScriptProcessor extends IndicScriptProcessor {
// first candidate target is after first non-half consonant
for (int i = 0; i < ng; i++) {
if ((i != source) && containsConsonant(gs, i)) {
if (! containsHalfConsonant(gs, i)) {
if (!containsHalfConsonant(gs, i)) {
c1 = i + 1;
break;
}
@@ -143,7 +138,7 @@ public class GurmukhiScriptProcessor extends IndicScriptProcessor {
}
// second candidate target is after last non-prebase matra after first candidate or before first syllable or vedic mark
for (int i = (c1 >= 0) ? c1 : 0; i < ng; i++) {
if (containsMatra(gs, i) && ! containsPreBaseMatra(gs, i)) {
if (containsMatra(gs, i) && !containsPreBaseMatra(gs, i)) {
c2 = i + 1;
} else if (containsOtherMark(gs, i)) {
c2 = i;
@@ -160,7 +155,7 @@ public class GurmukhiScriptProcessor extends IndicScriptProcessor {
}

private static boolean containsReph(GlyphSequence gs, int k) {
Boolean rphf = (Boolean) gs.getAssociation(k) . getPredication("rphf");
Boolean rphf = (Boolean) gs.getAssociation(k) .getPredication("rphf");
return (rphf != null) ? rphf.booleanValue() : false;
}

@@ -504,13 +499,13 @@ public class GurmukhiScriptProcessor extends IndicScriptProcessor {
}
}
static boolean isC(int c) {
return isType(c,C_C);
return isType(c, C_C);
}
static boolean isR(int c) {
return isType(c,C_C) && hasR(c);
return isType(c, C_C) && hasR(c);
}
static boolean isV(int c) {
return isType(c,C_V);
return isType(c, C_V);
}
static boolean isN(int c) {
return c == 0x0A3C;
@@ -519,10 +514,10 @@ public class GurmukhiScriptProcessor extends IndicScriptProcessor {
return c == 0x0A4D;
}
static boolean isM(int c) {
return isType(c,C_M);
return isType(c, C_M);
}
static boolean isPreM(int c) {
return isType(c,C_M) && hasFlag(c,C_PRE);
return isType(c, C_M) && hasFlag(c, C_PRE);
}
static boolean isX(int c) {
switch (typeOf(c)) {
@@ -536,10 +531,10 @@ public class GurmukhiScriptProcessor extends IndicScriptProcessor {
}
}
static boolean hasR(int c) {
return hasFlag(c,C_R);
return hasFlag(c, C_R);
}
static boolean hasN(int c) {
return hasFlag(c,C_N);
return hasFlag(c, C_N);
}

@Override

+ 4
- 13
src/java/org/apache/fop/complexscripts/scripts/IndicScriptProcessor.java View File

@@ -36,13 +36,6 @@ import org.apache.fop.complexscripts.util.GlyphContextTester;
import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.ScriptContextTester;

// CSOFF: AvoidNestedBlocksCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: SimplifyBooleanReturnCheck
// CSOFF: EmptyForIteratorPadCheck
// CSOFF: WhitespaceAfterCheck
// CSOFF: ParameterNumberCheck
// CSOFF: LineLengthCheck

/**
@@ -222,7 +215,7 @@ public class IndicScriptProcessor extends DefaultScriptProcessor {
}

private GlyphSequence[] syllabize(GlyphSequence gs, String script, String language) {
return Syllabizer.getSyllabizer(script, language, getSyllabizerClass()) . syllabize(gs);
return Syllabizer.getSyllabizer(script, language, getSyllabizerClass()) .syllabize(gs);
}

private GlyphSequence unsyllabize(GlyphSequence gs, GlyphSequence[] sa) {
@@ -384,12 +377,10 @@ public class IndicScriptProcessor extends DefaultScriptProcessor {
public boolean equals(Object o) {
if (o instanceof Syllabizer) {
Syllabizer s = (Syllabizer) o;
if (! s.script.equals(script)) {
return false;
} else if (! s.language.equals(language)) {
if (!s.script.equals(script)) {
return false;
} else {
return true;
return s.language.equals(language);
}
} else {
return false;
@@ -408,7 +399,7 @@ public class IndicScriptProcessor extends DefaultScriptProcessor {
}
return d;
}
private static Map<String,Syllabizer> syllabizers = new HashMap<String,Syllabizer>();
private static Map<String, Syllabizer> syllabizers = new HashMap<String, Syllabizer>();
static Syllabizer getSyllabizer(String script, String language, Class<? extends Syllabizer> syllabizerClass) {
String sid = makeSyllabizerId(script, language);
Syllabizer s = syllabizers.get(sid);

+ 3
- 9
src/java/org/apache/fop/complexscripts/scripts/ScriptProcessor.java View File

@@ -31,11 +31,7 @@ import org.apache.fop.complexscripts.util.CharScript;
import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.ScriptContextTester;

// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: ParameterNumberCheck
// CSOFF: SimplifyBooleanReturnCheck

/**
* <p>Abstract script processor base class for which an implementation of the substitution and positioning methods
@@ -278,14 +274,12 @@ public abstract class ScriptProcessor {
public boolean equals(Object o) {
if (o instanceof AssembledLookupsKey) {
AssembledLookupsKey k = (AssembledLookupsKey) o;
if (! table.equals(k.table)) {
if (!table.equals(k.table)) {
return false;
} else if (! Arrays.equals(features, k.features)) {
return false;
} else if (! lookups.equals(k.lookups)) {
} else if (!Arrays.equals(features, k.features)) {
return false;
} else {
return true;
return lookups.equals(k.lookups);
}
} else {
return false;

+ 17
- 23
src/java/org/apache/fop/complexscripts/util/CharScript.java View File

@@ -28,12 +28,6 @@ import java.util.Set;

import org.apache.fop.util.CharUtilities;

// CSOFF: AvoidNestedBlocksCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck
// CSOFF: SimplifyBooleanReturnCheck
// CSOFF: WhitespaceAfterCheck

/**
* <p>Script related utilities.</p>
*
@@ -41,6 +35,8 @@ import org.apache.fop.util.CharUtilities;
*/
public final class CharScript {

// CSOFF: LineLength

//
// The following script codes are based on ISO 15924. Codes less than 1000 are
// official assignments from 15924; those equal to or greater than 1000 are FOP
@@ -754,16 +750,14 @@ public final class CharScript {
case SCRIPT_UNCODED:
break;
default:
{
Integer v = (Integer) e.getValue();
assert v != null;
int c = v.intValue();
if (c > cMax) {
cMax = c;
sMax = s;
}
break;
Integer v = (Integer) e.getValue();
assert v != null;
int c = v.intValue();
if (c > cMax) {
cMax = c;
sMax = s;
}
break;
}
}
if (sMax < 0) {
@@ -823,7 +817,7 @@ public final class CharScript {
* @return a script tag
*/
public static String scriptTagFromCode(int code) {
Map<Integer,String> m = getScriptTagsMap();
Map<Integer, String> m = getScriptTagsMap();
if (m != null) {
String tag;
if ((tag = m.get(Integer.valueOf(code))) != null) {
@@ -842,7 +836,7 @@ public final class CharScript {
* @return a script code
*/
public static int scriptCodeFromTag(String tag) {
Map<String,Integer> m = getScriptCodeMap();
Map<String, Integer> m = getScriptCodeMap();
if (m != null) {
Integer c;
if ((c = m.get(tag)) != null) {
@@ -855,8 +849,8 @@ public final class CharScript {
}
}

private static Map<Integer,String> scriptTagsMap = null;
private static Map<String,Integer> scriptCodeMap = null;
private static Map<Integer, String> scriptTagsMap = null;
private static Map<String, Integer> scriptCodeMap = null;

private static void putScriptTag(Map tm, Map cm, int code, String tag) {
assert tag != null;
@@ -868,8 +862,8 @@ public final class CharScript {
}

private static void makeScriptMaps() {
HashMap<Integer,String> tm = new HashMap<Integer,String>();
HashMap<String,Integer> cm = new HashMap<String,Integer>();
HashMap<Integer, String> tm = new HashMap<Integer, String>();
HashMap<String, Integer> cm = new HashMap<String, Integer>();
putScriptTag(tm, cm, SCRIPT_HEBREW, "hebr");
putScriptTag(tm, cm, SCRIPT_MONGOLIAN, "mong");
putScriptTag(tm, cm, SCRIPT_ARABIC, "arab");
@@ -915,14 +909,14 @@ public final class CharScript {
scriptCodeMap = cm;
}

private static Map<Integer,String> getScriptTagsMap() {
private static Map<Integer, String> getScriptTagsMap() {
if (scriptTagsMap == null) {
makeScriptMaps();
}
return scriptTagsMap;
}

private static Map<String,Integer> getScriptCodeMap() {
private static Map<String, Integer> getScriptCodeMap() {
if (scriptCodeMap == null) {
makeScriptMaps();
}

+ 8
- 11
src/java/org/apache/fop/complexscripts/util/GlyphSequence.java View File

@@ -26,10 +26,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;

// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck
// CSOFF: WhitespaceAfterCheck
// CSOFF: NoWhitespaceAfterCheck

/**
* <p>A GlyphSequence encapsulates a sequence of character codes, a sequence of glyph codes,
@@ -639,10 +636,10 @@ public class GlyphSequence implements Cloneable {
private final int offset;
private final int count;
private final int[] subIntervals;
private Map<String,Object> predications;
private Map<String, Object> predications;

// class state
private static volatile Map<String,PredicationMerger> predicationMergers;
private static volatile Map<String, PredicationMerger> predicationMergers;

interface PredicationMerger {
Object merge(String key, Object v1, Object v2);
@@ -724,7 +721,7 @@ public class GlyphSequence implements Cloneable {
public boolean contained(int offset, int count) {
int s = offset;
int e = offset + count;
if (! isDisjoint()) {
if (!isDisjoint()) {
int s0 = getStart();
int e0 = getEnd();
return (s0 >= s) && (e0 <= e);
@@ -748,7 +745,7 @@ public class GlyphSequence implements Cloneable {
*/
public void setPredication(String key, Object value) {
if (predications == null) {
predications = new HashMap<String,Object>();
predications = new HashMap<String, Object>();
}
if (predications != null) {
predications.put(key, value);
@@ -775,7 +772,7 @@ public class GlyphSequence implements Cloneable {
*/
public void mergePredication(String key, Object value) {
if (predications == null) {
predications = new HashMap<String,Object>();
predications = new HashMap<String, Object>();
}
if (predications != null) {
if (predications.containsKey(key)) {
@@ -813,7 +810,7 @@ public class GlyphSequence implements Cloneable {
*/
public void mergePredications(CharAssociation ca) {
if (ca.predications != null) {
for (Map.Entry<String,Object> e : ca.predications.entrySet()) {
for (Map.Entry<String, Object> e : ca.predications.entrySet()) {
mergePredication(e.getKey(), e.getValue());
}
}
@@ -824,7 +821,7 @@ public class GlyphSequence implements Cloneable {
try {
CharAssociation ca = (CharAssociation) super.clone();
if (predications != null) {
ca.predications = new HashMap<String,Object>(predications);
ca.predications = new HashMap<String, Object>(predications);
}
return ca;
} catch (CloneNotSupportedException e) {
@@ -839,7 +836,7 @@ public class GlyphSequence implements Cloneable {
*/
public static void setPredicationMerger(String key, PredicationMerger pm) {
if (predicationMergers == null) {
predicationMergers = new HashMap<String,PredicationMerger>();
predicationMergers = new HashMap<String, PredicationMerger>();
}
if (predicationMergers != null) {
predicationMergers.put(key, pm);

+ 15
- 24
src/java/org/apache/fop/complexscripts/util/NumberConverter.java View File

@@ -23,9 +23,6 @@ import java.util.ArrayList;
import java.util.List;

// CSOFF: LineLengthCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: AvoidNestedBlocksCheck

/**
* <p>Implementation of Number to String Conversion algorithm specified by
@@ -186,10 +183,10 @@ public class NumberConverter {
separators.add(token.toArray(new Integer [ token.size() ]));
}
}
if (! separators.isEmpty()) {
if (!separators.isEmpty()) {
this.prefix = separators.remove(0);
}
if (! separators.isEmpty()) {
if (!separators.isEmpty()) {
this.suffix = separators.remove(separators.size() - 1);
}
this.separators = separators.toArray(new Integer [ separators.size() ] []);
@@ -260,33 +257,27 @@ public class NumberConverter {
int s = token[0].intValue();
switch (s) {
case (int) '1':
{
fn = formatNumberAsDecimal(number, (int) '1', 1);
break;
}
fn = formatNumberAsDecimal(number, (int) '1', 1);
break;
case (int) 'W':
case (int) 'w':
{
fn = formatNumberAsWord(number, (s == (int) 'W') ? Character.UPPERCASE_LETTER : Character.LOWERCASE_LETTER);
break;
}
fn = formatNumberAsWord(number, (s == (int) 'W') ? Character.UPPERCASE_LETTER : Character.LOWERCASE_LETTER);
break;
case (int) 'A': // handled as numeric sequence
case (int) 'a': // handled as numeric sequence
case (int) 'I': // handled as numeric special
case (int) 'i': // handled as numeric special
default:
{
if (isStartOfDecimalSequence(s)) {
fn = formatNumberAsDecimal(number, s, 1);
} else if (isStartOfAlphabeticSequence(s)) {
fn = formatNumberAsSequence(number, s, getSequenceBase(s), null);
} else if (isStartOfNumericSpecial(s)) {
fn = formatNumberAsSpecial(number, s);
} else {
fn = null;
}
break;
if (isStartOfDecimalSequence(s)) {
fn = formatNumberAsDecimal(number, s, 1);
} else if (isStartOfAlphabeticSequence(s)) {
fn = formatNumberAsSequence(number, s, getSequenceBase(s), null);
} else if (isStartOfNumericSpecial(s)) {
fn = formatNumberAsSpecial(number, s);
} else {
fn = null;
}
break;
}
} else if ((token.length == 2) && (token[0] == (int) 'W') && (token[1] == (int) 'w')) {
fn = formatNumberAsWord(number, Character.TITLECASE_LETTER);

+ 0
- 1
src/java/org/apache/fop/complexscripts/util/UTF32.java View File

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

import org.apache.fop.util.CharUtilities;

// CSOFF: InnerAssignmentCheck

/**
* <p>UTF32 related utilities.</p>

+ 4
- 1
src/java/org/apache/fop/fo/Constants.java View File

@@ -816,8 +816,11 @@ public interface Constants {
/** Scope for table header */
int PR_X_HEADER_COLUMN = 290;

/** For specifying PDF optional content group (layer) binding. */
int PR_X_LAYER = 291;

/** Number of property constants defined */
int PROPERTY_COUNT = 290;
int PROPERTY_COUNT = 291;

// compound property constants


+ 7
- 0
src/java/org/apache/fop/fo/FOPropertyMapping.java View File

@@ -2721,6 +2721,13 @@ public final class FOPropertyMapping implements Constants {
m.addEnum("auto", getEnumProperty(EN_AUTO, "AUTO"));
m.setDefault("auto");
addPropertyMaker("z-index", m);

// fox:layer
m = new StringProperty.Maker(PR_X_LAYER);
m.setInherited(false);
m.setDefault("");
addPropertyMaker("fox:layer", m);

}

private void createShorthandProperties() {

+ 30
- 3
src/java/org/apache/fop/fo/FObj.java View File

@@ -74,7 +74,8 @@ public abstract class FObj extends FONode implements Constants {
private int bidiLevel = -1;

// The value of properties relevant for all fo objects
private String id = null;
private String id;
private String layer;
// End of property values

/**
@@ -148,7 +149,7 @@ public abstract class FObj extends FONode implements Constants {
String attributeName = attList.getQName(i);
String attributeValue = attList.getValue(i);
Property prop = propertyList.getPropertyForAttribute(attList, attributeName, attributeValue);
if (prop.equals(value)) {
if (prop != null && prop.equals(value)) {
return attributeName;
}
}
@@ -173,6 +174,7 @@ public abstract class FObj extends FONode implements Constants {
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
layer = pList.get(PR_X_LAYER).getString();
}

/**
@@ -583,6 +585,16 @@ public abstract class FObj extends FONode implements Constants {
return (id != null && id.length() > 0);
}

/** @return the "layer" property. */
public String getLayer() {
return layer;
}

/** @return whether this object has an layer set */
public boolean hasLayer() {
return (layer != null && layer.length() > 0);
}

/** {@inheritDoc} */
public String getNamespaceURI() {
return FOElementMapping.URI;
@@ -611,7 +623,7 @@ public abstract class FObj extends FONode implements Constants {
if (bidiLevel >= 0) {
if ((this.bidiLevel < 0) || (bidiLevel < this.bidiLevel)) {
this.bidiLevel = bidiLevel;
if (parent != null) {
if ((parent != null) && !isBidiPropagationBoundary()) {
FObj foParent = (FObj) parent;
int parentBidiLevel = foParent.getBidiLevel();
if ((parentBidiLevel < 0) || (bidiLevel < parentBidiLevel)) {
@@ -646,10 +658,25 @@ public abstract class FObj extends FONode implements Constants {
return level;
}
}
if (isBidiInheritanceBoundary()) {
break;
}
}
return -1;
}

protected boolean isBidiBoundary(boolean propagate) {
return false;
}

private boolean isBidiInheritanceBoundary() {
return isBidiBoundary(false);
}

private boolean isBidiPropagationBoundary() {
return isBidiBoundary(true);
}

/**
* Add a new extension attachment to this FObj.
* (see org.apache.fop.fo.FONode for details)

+ 2
- 1
src/java/org/apache/fop/fo/expr/FunctionBase.java View File

@@ -36,7 +36,8 @@ public abstract class FunctionBase implements Function {
/** {@inheritDoc} */
public Property getOptionalArgDefault(int index, PropertyInfo pi) throws PropertyException {
if (index >= getOptionalArgsCount()) {
PropertyException e = new PropertyException(new IndexOutOfBoundsException("illegal optional argument index"));
PropertyException e = new PropertyException(
new IndexOutOfBoundsException("illegal optional argument index"));
e.setPropertyInfo(pi);
throw e;
} else {

+ 2
- 1
src/java/org/apache/fop/fo/expr/PropertyParser.java View File

@@ -385,7 +385,8 @@ public final class PropertyParser extends PropertyTokenizer {
}
int numArgs = args.size();
if (numArgs < numReq) {
throw new PropertyException("Expected " + numReq + " required arguments, but only " + numArgs + " specified");
throw new PropertyException("Expected " + numReq + " required arguments, but only "
+ numArgs + " specified");
} else {
for (int i = 0; i < numOpt; i++) {
if (args.size() < (numReq + i + 1)) {

+ 2
- 0
src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java View File

@@ -66,6 +66,8 @@ public class ExtensionElementMapping extends ElementMapping {
PROPERTY_ATTRIBUTES.add("border-before-end-radius");
PROPERTY_ATTRIBUTES.add("border-after-start-radius");
PROPERTY_ATTRIBUTES.add("border-after-end-radius");
//Optional content groups (layers)
PROPERTY_ATTRIBUTES.add("layer");
}

/**

+ 16
- 2
src/java/org/apache/fop/fo/flow/BlockContainer.java View File

@@ -98,7 +98,8 @@ public class BlockContainer extends FObj implements BreakPropertySet, WritingMod
referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric();
span = pList.get(PR_SPAN).getEnum();
writingModeTraits = new WritingModeTraits(
WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()));
WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()),
pList.getExplicit(PR_WRITING_MODE) != null);
disableColumnBalancing = pList.get(PR_X_DISABLE_COLUMN_BALANCING).getEnum();
}

@@ -280,6 +281,14 @@ public class BlockContainer extends FObj implements BreakPropertySet, WritingMod
return writingModeTraits.getWritingMode();
}

/**
* Obtain writing mode explicit indicator.
* @return the writing mode explicit indicator
*/
public boolean getExplicitWritingMode() {
return writingModeTraits.getExplicitWritingMode();
}

/** {@inheritDoc} */
public String getLocalName() {
return "block-container";
@@ -292,5 +301,10 @@ public class BlockContainer extends FObj implements BreakPropertySet, WritingMod
public int getNameId() {
return FO_BLOCK_CONTAINER;
}
}

@Override
protected boolean isBidiBoundary(boolean propagate) {
return getExplicitWritingMode();
}

}

+ 77
- 95
src/java/org/apache/fop/fo/flow/InlineContainer.java View File

@@ -37,49 +37,38 @@ import org.apache.fop.traits.Direction;
import org.apache.fop.traits.WritingMode;
import org.apache.fop.traits.WritingModeTraits;

/**
* Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_inline-container">
* <code>fo:inline-container</code></a> object.
*/
public class InlineContainer extends FObj {

// The value of FO traits (refined properties) that apply to fo:inline-container.
private Length alignmentAdjust;
private int alignmentBaseline;
private Length baselineShift;
private LengthRangeProperty inlineProgressionDimension;
private LengthRangeProperty blockProgressionDimension;
private int overflow;
private CommonBorderPaddingBackground commonBorderPaddingBackground;
private CommonMarginInline commonMarginInline;
private int clip;
private int dominantBaseline;
private LengthRangeProperty inlineProgressionDimension;
private Numeric referenceOrientation;
private int displayAlign;
private KeepProperty keepTogether;
private KeepProperty keepWithNext;
private KeepProperty keepWithPrevious;
private SpaceProperty lineHeight;
private int overflow;
private Numeric referenceOrientation;
private Length alignmentAdjust;
private int alignmentBaseline;
private Length baselineShift;
private int dominantBaseline;
private WritingModeTraits writingModeTraits;
// Unused but valid items, commented out for performance:
// private CommonRelativePosition commonRelativePosition;
// private int displayAlign;
// private Length height;
// private KeepProperty keepWithNext;
// private KeepProperty keepWithPrevious;
// private Length width;
// End of FO trait values

/** used for FO validation */
private boolean blockItemFound = false;
private boolean blockItemFound;

/**
* Base constructor
* Creates a new instance.
*
* @param parent {@link FONode} that is the parent of this object
* @param parent the parent of this inline-container
*/
public InlineContainer(FONode parent) {
super(parent);
}

/** {@inheritDoc} */
@Override
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength();
@@ -88,27 +77,31 @@ public class InlineContainer extends FObj {
blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonMarginInline = pList.getMarginInlineProps();
clip = pList.get(PR_CLIP).getEnum();
displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum();
dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
overflow = pList.get(PR_OVERFLOW).getEnum();
referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric();
writingModeTraits = new WritingModeTraits(
WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()));
WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()),
pList.getExplicit(PR_WRITING_MODE) != null);
}

/**
* {@inheritDoc}
* <br>XSL Content Model: marker* (%block;)+
*/
@Override
protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
if (FO_URI.equals(nsURI)) {
if (localName.equals("marker")) {
if (blockItemFound) {
nodesOutOfOrderError(loc, "fo:marker", "(%block;)");
nodesOutOfOrderError(loc, "fo:marker", "(%block;)+");
}
} else if (!isBlockItem(nsURI, localName)) {
invalidChildError(loc, nsURI, localName);
@@ -118,142 +111,131 @@ public class InlineContainer extends FObj {
}
}

/** {@inheritDoc} */
@Override
public void endOfNode() throws FOPException {
if (!blockItemFound) {
missingChildElementError("marker* (%block;)+");
}
}

/** @return the "alignment-adjust" FO trait */
public Length getAlignmentAdjust() {
return alignmentAdjust;
/** {@inheritDoc} */
public String getLocalName() {
return "inline-container";
}

/** @return the "alignment-baseline" FO trait */
public int getAlignmentBaseline() {
return alignmentBaseline;
/**
* {@inheritDoc}
* @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER}
*/
public int getNameId() {
return FO_INLINE_CONTAINER;
}

/** @return the "baseline-shift" FO trait */
public Length getBaselineShift() {
return baselineShift;
public LengthRangeProperty getInlineProgressionDimension() {
return inlineProgressionDimension;
}

/** @return the "block-progression-dimension" FO trait */
public LengthRangeProperty getBlockProgressionDimension() {
return blockProgressionDimension;
}

/** @return the "clip" FO trait */
public int getClip() {
return clip;
public int getOverflow() {
return overflow;
}

/**@return Returns the {@link CommonBorderPaddingBackground} */
public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
return this.commonBorderPaddingBackground;
}

/** @return Returns the {@link CommonMarginInline} */
public CommonMarginInline getCommonMarginInline() {
return this.commonMarginInline;
}

/** @return the "dominant-baseline" FO trait */
public int getDominantBaseline() {
return dominantBaseline;
public int getReferenceOrientation() {
return referenceOrientation.getValue();
}

public int getDisplayAlign() {
return this.displayAlign;
}

public KeepProperty getKeepWithPrevious() {
return keepWithPrevious;
}

/** @return the "keep-together" FO trait */
public KeepProperty getKeepTogether() {
return keepTogether;
}

/** @return the "inline-progression-dimension" FO trait */
public LengthRangeProperty getInlineProgressionDimension() {
return inlineProgressionDimension;
public KeepProperty getKeepWithNext() {
return keepWithNext;
}

/** @return the "line-height" FO trait */
public SpaceProperty getLineHeight() {
return lineHeight;
}

/** @return the "overflow" FO trait */
public int getOverflow() {
return overflow;
public Length getAlignmentAdjust() {
return alignmentAdjust;
}

/** @return the "reference-orientation" FO trait */
public int getReferenceOrientation() {
return referenceOrientation.getValue();
public int getAlignmentBaseline() {
return alignmentBaseline;
}

public Length getBaselineShift() {
return baselineShift;
}

public int getDominantBaseline() {
return dominantBaseline;
}

public WritingMode getWritingMode() {
return writingModeTraits.getWritingMode();
}

/**
* Obtain inline progression direction.
* @return the inline progression direction
* Obtain writing mode explicit indicator.
* @return the writing mode explicit indicator
*/
public boolean getExplicitWritingMode() {
return writingModeTraits.getExplicitWritingMode();
}

public Direction getInlineProgressionDirection() {
return writingModeTraits.getInlineProgressionDirection();
}

/**
* Obtain block progression direction.
* @return the block progression direction
*/
public Direction getBlockProgressionDirection() {
return writingModeTraits.getBlockProgressionDirection();
}

/**
* Obtain column progression direction.
* @return the column progression direction
*/
public Direction getColumnProgressionDirection() {
return writingModeTraits.getColumnProgressionDirection();
}

/**
* Obtain row progression direction.
* @return the row progression direction
*/
public Direction getRowProgressionDirection() {
return writingModeTraits.getRowProgressionDirection();
}

/**
* Obtain (baseline) shift direction.
* @return the (baseline) shift direction
*/
public Direction getShiftDirection() {
return writingModeTraits.getShiftDirection();
}

/**
* Obtain writing mode.
* @return the writing mode
*/
public WritingMode getWritingMode() {
return writingModeTraits.getWritingMode();
}

/** {@inheritDoc} */
public String getLocalName() {
return "inline-container";
@Override
public boolean isDelimitedTextRangeBoundary(int boundary) {
return false;
}

/**
* {@inheritDoc}
* @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER}
*/
public int getNameId() {
return FO_INLINE_CONTAINER;
@Override
public boolean generatesReferenceAreas() {
return true;
}

@Override
public boolean isDelimitedTextRangeBoundary(int boundary) {
return false;
protected boolean isBidiBoundary(boolean propagate) {
return getExplicitWritingMode();
}

}

+ 12
- 1
src/java/org/apache/fop/fo/flow/table/Table.java View File

@@ -139,7 +139,8 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
tableOmitFooterAtBreak = pList.get(PR_TABLE_OMIT_FOOTER_AT_BREAK).getEnum();
tableOmitHeaderAtBreak = pList.get(PR_TABLE_OMIT_HEADER_AT_BREAK).getEnum();
writingModeTraits = new WritingModeTraits(
WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()));
WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()),
pList.getExplicit(PR_WRITING_MODE) != null);

//Bind extension properties
widowContentLimit = pList.get(PR_X_WIDOW_CONTENT_LIMIT).getLength();
@@ -554,6 +555,11 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
return writingModeTraits.getWritingMode();
}

/** {@inheritDoc} */
public boolean getExplicitWritingMode() {
return writingModeTraits.getExplicitWritingMode();
}

/** @return the "fox:widow-content-limit" extension FO trait */
public Length getWidowContentLimit() {
return widowContentLimit;
@@ -620,4 +626,9 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
return ranges;
}

@Override
protected boolean isBidiBoundary(boolean propagate) {
return getExplicitWritingMode();
}

}

+ 17
- 1
src/java/org/apache/fop/fo/pagination/PageSequence.java View File

@@ -96,7 +96,8 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra
masterReference = pList.get(PR_MASTER_REFERENCE).getString();
referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric();
writingModeTraits = new WritingModeTraits(
WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()));
WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()),
pList.getExplicit(PR_WRITING_MODE) != null);
if (masterReference == null || masterReference.equals("")) {
missingPropertyError("master-reference");
}
@@ -403,6 +404,16 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra
}
}

/**
* {@inheritDoc}
*/
public boolean getExplicitWritingMode() {
if (writingModeTraits != null) {
return writingModeTraits.getExplicitWritingMode();
} else {
return false;
}
}

@Override
protected Stack collectDelimitedTextRanges(Stack ranges, DelimitedTextRange currentRange) {
@@ -423,6 +434,11 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra
return ranges;
}

@Override
protected boolean isBidiBoundary(boolean propagate) {
return true;
}

/**
* Releases a page-sequence's children after the page-sequence has been fully processed.
*/

+ 5
- 1
src/java/org/apache/fop/fo/properties/GenericShorthandParser.java View File

@@ -83,13 +83,17 @@ public class GenericShorthandParser implements ShorthandParser {
PropertyList propertyList)
throws PropertyException {
Property prop = null;
String vProperty = "";
// Try each of the stored values in turn
Iterator iprop = property.getList().iterator();
while (iprop.hasNext() && prop == null) {
Property p = (Property)iprop.next();
if (p.getNCname() != null) {
vProperty += p.getNCname() + " ";
}
prop = maker.convertShorthandProperty(propertyList, p, null);
propertyList.validatePropertyValue(p.getNCname(), prop, property);
}
propertyList.validatePropertyValue(vProperty.trim(), prop, property);
return prop;
}


+ 2
- 2
src/java/org/apache/fop/fonts/FontLoader.java View File

@@ -26,7 +26,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.truetype.TTFFontLoader;
import org.apache.fop.fonts.truetype.OFFontLoader;
import org.apache.fop.fonts.type1.Type1FontLoader;

/**
@@ -105,7 +105,7 @@ public abstract class FontLoader {
}
loader = new Type1FontLoader(fontFileURI, embedded, useKerning, resourceResolver);
} else {
loader = new TTFFontLoader(fontFileURI, subFontName, embedded, embeddingMode,
loader = new OFFontLoader(fontFileURI, subFontName, embedded, embeddingMode,
encodingMode, useKerning, useAdvanced, resourceResolver);
}
return loader.getFont();

+ 10
- 6
src/java/org/apache/fop/fonts/FontManagerConfigurator.java View File

@@ -48,20 +48,24 @@ public class FontManagerConfigurator {

private final Configuration cfg;

private final URI defaultBaseUri;
private final URI baseURI;

private final URI fallbackURI;

private final ResourceResolver resourceResolver;

/**
* Main constructor
* @param cfg the font manager configuration object
* @param defaultBaseUri the default URI base to use for URI resolution
* @param baseURI the URI against which to resolve relative URIs
* @param fallbackURI the URI to use as a fallback if font-base is unspecified
* @param resourceResolver the resource resolver
*/
public FontManagerConfigurator(Configuration cfg, URI defaultBaseUri,
public FontManagerConfigurator(Configuration cfg, URI baseURI, URI fallbackURI,
ResourceResolver resourceResolver) {
this.cfg = cfg;
this.defaultBaseUri = defaultBaseUri;
this.baseURI = baseURI;
this.fallbackURI = fallbackURI;
this.resourceResolver = resourceResolver;
}

@@ -77,13 +81,13 @@ public class FontManagerConfigurator {
URI fontBase = InternalResourceResolver.getBaseURI(cfg.getChild("font-base")
.getValue(null));
fontManager.setResourceResolver(ResourceResolverFactory.createInternalResourceResolver(
defaultBaseUri.resolve(fontBase), resourceResolver));
baseURI.resolve(fontBase), resourceResolver));
} catch (URISyntaxException use) {
LogUtil.handleException(log, use, true);
}
} else {
fontManager.setResourceResolver(ResourceResolverFactory.createInternalResourceResolver(
defaultBaseUri, resourceResolver));
fallbackURI, resourceResolver));
}
// caching (fonts)
if (cfg.getChild("use-cache", false) != null) {

+ 2
- 1
src/java/org/apache/fop/fonts/FontTriplet.java View File

@@ -27,7 +27,8 @@ import java.io.Serializable;
*/
public class FontTriplet implements Comparable<FontTriplet>, Serializable {

public static final FontTriplet DEFAULT_FONT_TRIPLET = new FontTriplet("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
public static final FontTriplet DEFAULT_FONT_TRIPLET
= new FontTriplet("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);

/** serial version UID */
private static final long serialVersionUID = 1168991106658033508L;

+ 52
- 17
src/java/org/apache/fop/fonts/MultiByteFont.java View File

@@ -23,6 +23,7 @@ import java.awt.Rectangle;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.util.BitSet;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
@@ -71,6 +72,15 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
/** Contains the character bounding boxes for all characters in the font */
protected Rectangle[] boundingBoxes;

private boolean isOTFFile = false;

// since for most users the most likely glyphs are in the first cmap segments we store their mapping.
private static final int NUM_MOST_LIKELY_GLYPHS = 256;
private int[] mostLikelyGlyphs = new int[NUM_MOST_LIKELY_GLYPHS];

//A map to store each used glyph from the CID set against the glyph name.
private LinkedHashMap<Integer, String> usedGlyphNames = new LinkedHashMap<Integer, String>();

/**
* Default constructor
*/
@@ -115,6 +125,14 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
return cidType;
}

public void setIsOTFFile(boolean isOTFFile) {
this.isOTFFile = isOTFFile;
}

public boolean isOTFFile() {
return this.isOTFFile;
}

/**
* Sets the CIDType.
* @param cidType The cidType to set
@@ -151,6 +169,14 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
return this.cidSet;
}

public void mapUsedGlyphName(int gid, String value) {
usedGlyphNames.put(gid, value);
}

public LinkedHashMap<Integer, String> getUsedGlyphNames() {
return usedGlyphNames;
}

/** {@inheritDoc} */
@Override
public String getEncodingName() {
@@ -187,10 +213,15 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
* @return the glyph index (or 0 if the glyph is not available)
*/
// [TBD] - needs optimization, i.e., change from linear search to binary search
private int findGlyphIndex(int c) {
public int findGlyphIndex(int c) {
int idx = c;
int retIdx = SingleByteEncoding.NOT_FOUND_CODE_POINT;

// for most users the most likely glyphs are in the first cmap segments (meaning the one with
// the lowest unicode start values)
if (idx < NUM_MOST_LIKELY_GLYPHS && mostLikelyGlyphs[idx] != 0) {
return mostLikelyGlyphs[idx];
}
for (int i = 0; (i < cmap.length) && retIdx == 0; i++) {
if (cmap[i].getUnicodeStart() <= idx
&& cmap[i].getUnicodeEnd() >= idx) {
@@ -198,6 +229,9 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
retIdx = cmap[i].getGlyphStartIndex()
+ idx
- cmap[i].getUnicodeStart();
if (idx < NUM_MOST_LIKELY_GLYPHS) {
mostLikelyGlyphs[idx] = retIdx;
}
}
}
return retIdx;
@@ -291,22 +325,6 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
return findCharacterFromGlyphIndex(gi, true);
}


/** {@inheritDoc} */
@Override
public char mapChar(char c) {
notifyMapOperation();
int glyphIndex = findGlyphIndex(c);
if (glyphIndex == SingleByteEncoding.NOT_FOUND_CODE_POINT) {
warnMissingGlyph(c);
glyphIndex = findGlyphIndex(Typeface.NOT_FOUND);
}
if (isEmbeddable()) {
glyphIndex = cidSet.mapChar(glyphIndex, c);
}
return (char) glyphIndex;
}

protected BitSet getGlyphIndices() {
BitSet bitset = new BitSet();
bitset.set(0);
@@ -337,6 +355,23 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
return chars;
}

/** {@inheritDoc} */
@Override
public char mapChar(char c) {
notifyMapOperation();
int glyphIndex = findGlyphIndex(c);
if (glyphIndex == SingleByteEncoding.NOT_FOUND_CODE_POINT) {
warnMissingGlyph(c);
if (!isOTFFile) {
glyphIndex = findGlyphIndex(Typeface.NOT_FOUND);
}
}
if (isEmbeddable()) {
glyphIndex = cidSet.mapChar(glyphIndex, c);
}
return (char) glyphIndex;
}

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

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

@@ -33,7 +33,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.fonts.Glyphs;

import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;
import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion;

/**
* Generic SingleByte font

+ 0
- 6
src/java/org/apache/fop/fonts/apps/AbstractFontReader.java View File

@@ -32,8 +32,6 @@ import javax.xml.transform.TransformerFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.util.CommandLineLogger;

/**
* Abstract base class for the PFM and TTF Reader command-line applications.
*/
@@ -90,10 +88,6 @@ public abstract class AbstractFontReader {
protected static void setLogLevel(String level) {
// Set the evel for future loggers.
LogFactory.getFactory().setAttribute("level", level);
if (log instanceof CommandLineLogger) {
// Set the level for the logger creates already.
((CommandLineLogger) log).setLogLevel(level);
}
}

/**

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

@@ -29,11 +29,8 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.commons.logging.LogFactory;

import org.apache.fop.Version;
import org.apache.fop.fonts.type1.PFMFile;
import org.apache.fop.util.CommandLineLogger;

/**
* A tool which reads PFM files from Adobe Type 1 fonts and creates
@@ -92,14 +89,6 @@ public class PFMReader extends AbstractFontReader {
Map options = new java.util.HashMap();
String[] arguments = parseArguments(options, args);

// Enable the simple command line logging when no other logger is
// defined.
LogFactory logFactory = LogFactory.getFactory();
if (System.getProperty("org.apache.commons.logging.Log") == null) {
logFactory.setAttribute("org.apache.commons.logging.Log",
CommandLineLogger.class.getName());
}

determineLogLevel(options);

PFMReader app = new PFMReader();

+ 3
- 13
src/java/org/apache/fop/fonts/apps/TTFReader.java View File

@@ -32,16 +32,13 @@ import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import org.apache.commons.logging.LogFactory;

import org.apache.fop.Version;
import org.apache.fop.fonts.CMapSegment;
import org.apache.fop.fonts.FontUtil;
import org.apache.fop.fonts.truetype.FontFileReader;
import org.apache.fop.fonts.truetype.OFFontLoader;
import org.apache.fop.fonts.truetype.TTFFile;
import org.apache.fop.util.CommandLineLogger;

// CSOFF: InnerAssignmentCheck
// CSOFF: LineLengthCheck

/**
@@ -123,14 +120,6 @@ public class TTFReader extends AbstractFontReader {
Map options = new java.util.HashMap();
String[] arguments = parseArguments(options, args);

// Enable the simple command line logging when no other logger is
// defined.
LogFactory logFactory = LogFactory.getFactory();
if (System.getProperty("org.apache.commons.logging.Log") == null) {
logFactory.setAttribute("org.apache.commons.logging.Log",
CommandLineLogger.class.getName());
}

determineLogLevel(options);

TTFReader app = new TTFReader();
@@ -224,7 +213,8 @@ public class TTFReader extends AbstractFontReader {
InputStream stream = new FileInputStream(fileName);
try {
FontFileReader reader = new FontFileReader(stream);
boolean supported = ttfFile.readFont(reader, fontName);
String header = OFFontLoader.readHeader(reader);
boolean supported = ttfFile.readFont(reader, header, fontName);
if (!supported) {
return null;
}

+ 2
- 2
src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java View File

@@ -43,8 +43,8 @@ import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.FontUtil;
import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.fonts.truetype.FontFileReader;
import org.apache.fop.fonts.truetype.OFFontLoader;
import org.apache.fop.fonts.truetype.TTFFile;
import org.apache.fop.fonts.truetype.TTFFontLoader;

/**
* Attempts to determine correct FontInfo
@@ -220,7 +220,7 @@ public class FontInfoFinder {
log.debug("Loading " + fontName);
}
try {
TTFFontLoader ttfLoader = new TTFFontLoader(fontURI, fontName, true,
OFFontLoader ttfLoader = new OFFontLoader(fontURI, fontName, true,
EmbeddingMode.AUTO, EncodingMode.AUTO, useKerning, useAdvanced,
resourceResolver);
customFont = ttfLoader.getFont();

+ 927
- 0
src/java/org/apache/fop/fonts/cff/CFFDataReader.java View File

@@ -0,0 +1,927 @@
/*
* 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.cff;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.fontbox.cff.CFFDataInput;
import org.apache.fontbox.cff.CFFOperator;

import org.apache.fop.fonts.truetype.FontFileReader;
import org.apache.fop.fonts.truetype.OTFFile;

/**
* A class to read the CFF data from an OTF CFF font file.
*/
public class CFFDataReader {
private CFFDataInput cffData;

private byte[] header;
private CFFIndexData nameIndex;
private CFFIndexData topDICTIndex;
private CFFIndexData stringIndex;
private CFFIndexData charStringIndex;
private CFFIndexData globalIndexSubr;
private CFFIndexData localIndexSubr;
private CustomEncoding encoding;
private FDSelect fdSelect;
private List<FontDict> fdFonts;

private static final int DOUBLE_BYTE_OPERATOR = 12;
private static final int NUM_STANDARD_STRINGS = 391;

/** Commonly used parsed dictionaries */
private LinkedHashMap<String, DICTEntry> topDict;

public CFFDataReader() {

}

/**
* Constructor for the CFF data reader which accepts the CFF byte data
* as an argument.
* @param cffDataArray A byte array which holds the CFF data
*/
public CFFDataReader(byte[] cffDataArray) throws IOException {
cffData = new CFFDataInput(cffDataArray);
readCFFData();
}

/**
* Constructor for the CFF data reader which accepts a FontFileReader object
* which points to the original font file as an argument.
* @param fontFile The font file as represented by a FontFileReader object
*/
public CFFDataReader(FontFileReader fontFile) throws IOException {
cffData = new CFFDataInput(OTFFile.getCFFData(fontFile));
readCFFData();
}

private void readCFFData() throws IOException {
header = readHeader();
nameIndex = readIndex();
topDICTIndex = readIndex();
topDict = parseDictData(topDICTIndex.getData());
stringIndex = readIndex();
globalIndexSubr = readIndex();
charStringIndex = readCharStringIndex();
encoding = readEncoding();
fdSelect = readFDSelect();
localIndexSubr = readLocalIndexSubrs();
fdFonts = parseCIDData();
}

public Map<String, DICTEntry> getPrivateDict(DICTEntry privateEntry) throws IOException {
return parseDictData(getPrivateDictBytes(privateEntry));
}

public byte[] getPrivateDictBytes(DICTEntry privateEntry) throws IOException {
int privateLength = privateEntry.getOperands().get(0).intValue();
int privateOffset = privateEntry.getOperands().get(1).intValue();
return getCFFOffsetBytes(privateOffset, privateLength);
}

/**
* Retrieves a number of bytes from the CFF data stream
* @param offset The offset of the bytes to retrieve
* @param length The number of bytes to retrieve
* @return Returns a byte array of requested bytes
* @throws IOException Throws an IO Exception if an error occurs
*/
private byte[] getCFFOffsetBytes(int offset, int length) throws IOException {
cffData.setPosition(offset);
return cffData.readBytes(length);
}

/**
* Parses the dictionary data and returns a map of objects for each entry
* @param dictData The data for the dictionary data
* @return Returns a map of type DICTEntry identified by the operand name
* @throws IOException Throws an IO Exception if an error occurs
*/
public LinkedHashMap<String, DICTEntry> parseDictData(byte[] dictData) throws IOException {
LinkedHashMap<String, DICTEntry> dictEntries = new LinkedHashMap<String, DICTEntry>();
List<Number> operands = new ArrayList<Number>();
List<Integer> operandLengths = new ArrayList<Integer>();
int lastOperandLength = 0;
for (int i = 0; i < dictData.length; i++) {
int readByte = dictData[i] & 0xFF;
if (readByte < 28) {
int[] operator = new int[(readByte == DOUBLE_BYTE_OPERATOR) ? 2 : 1];
if (readByte == DOUBLE_BYTE_OPERATOR) {
operator[0] = dictData[i];
operator[1] = dictData[i + 1];
i++;
} else {
operator[0] = dictData[i];
}
String operatorName = "";
CFFOperator tempOp = null;
if (operator.length > 1) {
tempOp = CFFOperator.getOperator(new CFFOperator.Key(operator[0], operator[1]));
} else {
tempOp = CFFOperator.getOperator(new CFFOperator.Key(operator[0]));
}
if (tempOp != null) {
operatorName = tempOp.getName();
}
DICTEntry newEntry = new DICTEntry();
newEntry.setOperator(operator);
newEntry.setOperands(new ArrayList<Number>(operands));
newEntry.setOperatorName(operatorName);
newEntry.setOffset(i - lastOperandLength);
newEntry.setOperandLength(lastOperandLength);
newEntry.setOperandLengths(new ArrayList<Integer>(operandLengths));
byte[] byteData = new byte[lastOperandLength + operator.length];
System.arraycopy(dictData, i - operator.length - (lastOperandLength - 1),
byteData, 0, operator.length + lastOperandLength);
newEntry.setByteData(byteData);
dictEntries.put(operatorName, newEntry);
operands.clear();
operandLengths.clear();
lastOperandLength = 0;
} else {
if (readByte >= 32 && readByte <= 246) {
operands.add(readByte - 139);
lastOperandLength += 1;
operandLengths.add(1);
} else if (readByte >= 247 && readByte <= 250) {
operands.add((readByte - 247) * 256 + (dictData[i + 1] & 0xFF) + 108);
lastOperandLength += 2;
operandLengths.add(2);
i++;
} else if (readByte >= 251 && readByte <= 254) {
operands.add(-(readByte - 251) * 256 - (dictData[i + 1] & 0xFF) - 108);
lastOperandLength += 2;
operandLengths.add(2);
i++;
} else if (readByte == 28) {
operands.add((dictData[i + 1] & 0xFF) << 8 | (dictData[i + 2] & 0xFF));
lastOperandLength += 3;
operandLengths.add(3);
i += 2;
} else if (readByte == 29) {
operands.add((dictData[i + 1] & 0xFF) << 24 | (dictData[i + 2] & 0xFF) << 16
| (dictData[i + 3] & 0xFF) << 8 | (dictData[i + 4] & 0xFF));
lastOperandLength += 5;
operandLengths.add(5);
i += 4;
} else if (readByte == 30) {
boolean terminatorFound = false;
StringBuilder realNumber = new StringBuilder();
int byteCount = 1;
do {
byte nibblesByte = dictData[++i];
byteCount++;
terminatorFound = readNibble(realNumber, (nibblesByte >> 4) & 0x0F);
if (!terminatorFound) {
terminatorFound = readNibble(realNumber, nibblesByte & 0x0F);
}
} while (!terminatorFound);
operands.add(Double.valueOf(realNumber.toString()));
lastOperandLength += byteCount;
operandLengths.add(byteCount);
}
}
}
return dictEntries;
}

private boolean readNibble(StringBuilder realNumber, int nibble) {
if (nibble <= 0x9) {
realNumber.append(nibble);
} else {
switch (nibble) {
case 0xa: realNumber.append("."); break;
case 0xb: realNumber.append("E"); break;
case 0xc: realNumber.append("E-"); break;
case 0xd: break;
case 0xe: realNumber.append("-"); break;
case 0xf: return true;
default: throw new AssertionError("Unexpected nibble value");
}
}
return false;
}

/**
* A class containing data for a dictionary entry
*/
public static class DICTEntry {
private int[] operator;
private List<Number> operands;
private List<Integer> operandLengths;
private String operatorName;
private int offset;
private int operandLength;
private byte[] data = new byte[0];

public void setOperator(int[] operator) {
this.operator = operator;
}

public int[] getOperator() {
return this.operator;
}

public void setOperands(List<Number> operands) {
this.operands = operands;
}

public List<Number> getOperands() {
return this.operands;
}

public void setOperatorName(String operatorName) {
this.operatorName = operatorName;
}

public String getOperatorName() {
return this.operatorName;
}

public void setOffset(int offset) {
this.offset = offset;
}

public int getOffset() {
return this.offset;
}

public void setOperandLength(int operandLength) {
this.operandLength = operandLength;
}

public int getOperandLength() {
return this.operandLength;
}

public void setByteData(byte[] data) {
this.data = data.clone();
}

public byte[] getByteData() {
return data.clone();
}

public void setOperandLengths(List<Integer> operandLengths) {
this.operandLengths = operandLengths;
}

public List<Integer> getOperandLengths() {
return operandLengths;
}
}

private byte[] readHeader() throws IOException {
//Read known header
byte[] fixedHeader = cffData.readBytes(4);
int hdrSize = (fixedHeader[2] & 0xFF);
byte[] extra = cffData.readBytes(hdrSize - 4);
byte[] header = new byte[hdrSize];
for (int i = 0; i < fixedHeader.length; i++) {
header[i] = fixedHeader[i];
}
for (int i = 4; i < extra.length; i++) {
header[i] = extra[i - 4];
}
return header;
}

/**
* Reads a CFF index object are the specified offset position
* @param offset The position of the index object to read
* @return Returns an object representing the index
* @throws IOException Throws an IO Exception if an error occurs
*/
public CFFIndexData readIndex(int offset) throws IOException {
cffData.setPosition(offset);
return readIndex();
}

private CFFIndexData readIndex() throws IOException {
return readIndex(cffData);
}

/**
* Reads an index from the current position of the CFFDataInput object
* @param input The object holding the CFF byte data
* @return Returns an object representing the index
* @throws IOException Throws an IO Exception if an error occurs
*/
public CFFIndexData readIndex(CFFDataInput input) throws IOException {
CFFIndexData nameIndex = new CFFIndexData();
if (input != null) {
int origPos = input.getPosition();
nameIndex.parseIndexHeader(input);
int tableSize = input.getPosition() - origPos;
nameIndex.setByteData(input.getPosition() - tableSize, tableSize);
}
return nameIndex;
}

/**
* Retrieves the SID for the given GID object
* @param charsetOffset The offset of the charset data
* @param GID The GID for which to retrieve the SID
* @return Returns the SID as an integer
*/
public int getSIDFromGID(int charsetOffset, int gid) throws IOException {
if (gid == 0) {
return 0;
}
cffData.setPosition(charsetOffset);
int charsetFormat = cffData.readCard8();
switch (charsetFormat) {
case 0: //Adjust for .notdef character
cffData.setPosition(cffData.getPosition() + (--gid * 2));
return cffData.readSID();
case 1: return getSIDFromGIDFormat(gid, 1);
case 2: return getSIDFromGIDFormat(gid, 2);
default: return 0;
}
}

private int getSIDFromGIDFormat(int gid, int format) throws IOException {
int glyphCount = 0;
while (true) {
int oldGlyphCount = glyphCount;
int start = cffData.readSID();
glyphCount += ((format == 1) ? cffData.readCard8() : cffData.readCard16()) + 1;
if (gid <= glyphCount) {
return start + (gid - oldGlyphCount) - 1;
}
}
}

public byte[] getHeader() {
return header.clone();
}

public CFFIndexData getNameIndex() {
return nameIndex;
}

public CFFIndexData getTopDictIndex() {
return topDICTIndex;
}

public LinkedHashMap<String, DICTEntry> getTopDictEntries() {
return topDict;
}

public CFFIndexData getStringIndex() {
return stringIndex;
}

public CFFIndexData getGlobalIndexSubr() {
return globalIndexSubr;
}

public CFFIndexData getLocalIndexSubr() {
return localIndexSubr;
}

public CFFIndexData getCharStringIndex() {
return charStringIndex;
}

public CFFDataInput getCFFData() {
return cffData;
}

public CustomEncoding getEncoding() {
return encoding;
}

public FDSelect getFDSelect() {
return fdSelect;
}

public List<FontDict> getFDFonts() {
return fdFonts;
}

public CFFDataInput getLocalSubrsForGlyph(int glyph) throws IOException {
//Subsets are currently written using a Format0 FDSelect
FDSelect fontDictionary = getFDSelect();
if (fontDictionary instanceof Format0FDSelect) {
Format0FDSelect fdSelect = (Format0FDSelect)fontDictionary;
int found = fdSelect.getFDIndexes()[glyph];
FontDict font = getFDFonts().get(found);
byte[] localSubrData = font.getLocalSubrData().getByteData();
if (localSubrData != null) {
return new CFFDataInput(localSubrData);
} else {
return null;
}
} else if (fontDictionary instanceof Format3FDSelect) {
Format3FDSelect fdSelect = (Format3FDSelect)fontDictionary;
int index = 0;
for (int first : fdSelect.getRanges().keySet()) {
if (first > glyph) {
break;
}
index++;
}
FontDict font = getFDFonts().get(index);
byte[] localSubrsData = font.getLocalSubrData().getByteData();
if (localSubrsData != null) {
return new CFFDataInput(localSubrsData);
} else {
return null;
}
}
return null;
}

/**
* Parses the char string index from the CFF byte data
* @param offset The offset to the char string index
* @return Returns the char string index object
* @throws IOException Throws an IO Exception if an error occurs
*/
public CFFIndexData readCharStringIndex() throws IOException {
int offset = topDict.get("CharStrings").getOperands().get(0).intValue();
cffData.setPosition(offset);
return readIndex();
}

private CustomEncoding readEncoding() throws IOException {
CustomEncoding foundEncoding = null;
if (topDict.get("Encoding") != null) {
int offset = topDict.get("Encoding").getOperands().get(0).intValue();
if (offset != 0 && offset != 1) {
//No need to set the offset as we are reading the data sequentially.
int format = cffData.readCard8();
int numEntries = cffData.readCard8();
switch (format) {
case 0:
foundEncoding = readFormat0Encoding(format, numEntries);
break;
case 1:
foundEncoding = readFormat1Encoding(format, numEntries);
break;
default: break;
}
}
}
return foundEncoding;
}

private Format0Encoding readFormat0Encoding(int format, int numEntries)
throws IOException {
Format0Encoding newEncoding = new Format0Encoding();
newEncoding.setFormat(format);
newEncoding.setNumEntries(numEntries);
int[] codes = new int[numEntries];
for (int i = 0; i < numEntries; i++) {
codes[i] = cffData.readCard8();
}
newEncoding.setCodes(codes);
return newEncoding;
}

private Format1Encoding readFormat1Encoding(int format, int numEntries)
throws IOException {
Format1Encoding newEncoding = new Format1Encoding();
newEncoding.setFormat(format);
newEncoding.setNumEntries(numEntries);
LinkedHashMap<Integer, Integer> ranges = new LinkedHashMap<Integer, Integer>();
for (int i = 0; i < numEntries; i++) {
int first = cffData.readCard8();
int left = cffData.readCard8();
ranges.put(first, left);
}
newEncoding.setRanges(ranges);
return newEncoding;
}

private FDSelect readFDSelect() throws IOException {
FDSelect fdSelect = null;
DICTEntry fdSelectEntry = topDict.get("FDSelect");
if (fdSelectEntry != null) {
int fdOffset = fdSelectEntry.getOperands().get(0).intValue();
cffData.setPosition(fdOffset);
int format = cffData.readCard8();
switch (format) {
case 0:
fdSelect = readFormat0FDSelect();
break;
case 3:
fdSelect = readFormat3FDSelect();
break;
default:
}
}
return fdSelect;
}

private Format0FDSelect readFormat0FDSelect() throws IOException {
Format0FDSelect newFDs = new Format0FDSelect();
newFDs.setFormat(0);
int glyphCount = charStringIndex.getNumObjects();
int[] fds = new int[glyphCount];
for (int i = 0; i < glyphCount; i++) {
fds[i] = cffData.readCard8();
}
newFDs.setFDIndexes(fds);
return newFDs;
}

private Format3FDSelect readFormat3FDSelect() throws IOException {
Format3FDSelect newFDs = new Format3FDSelect();
newFDs.setFormat(3);
int rangeCount = cffData.readCard16();
newFDs.setRangeCount(rangeCount);
LinkedHashMap<Integer, Integer> ranges = new LinkedHashMap<Integer, Integer>();
for (int i = 0; i < rangeCount; i++) {
int first = cffData.readCard16();
int fd = cffData.readCard8();
ranges.put(first, fd);
}
newFDs.setRanges(ranges);
newFDs.setSentinelGID(cffData.readCard16());
return newFDs;
}

private List<FontDict> parseCIDData() throws IOException {
ArrayList<FontDict> fdFonts = new ArrayList<FontDict>();
if (topDict.get("ROS") != null) {
DICTEntry fdArray = topDict.get("FDArray");
if (fdArray != null) {
int fdIndex = fdArray.getOperands().get(0).intValue();
CFFIndexData fontDicts = readIndex(fdIndex);
for (int i = 0; i < fontDicts.getNumObjects(); i++) {
FontDict newFontDict = new FontDict();

byte[] fdData = fontDicts.getValue(i);
LinkedHashMap<String, DICTEntry> fdEntries = parseDictData(fdData);
newFontDict.setByteData(fontDicts.getValuePosition(i), fontDicts.getValueLength(i));
DICTEntry fontFDEntry = fdEntries.get("FontName");
newFontDict.setFontName(getString(fontFDEntry.getOperands().get(0).intValue()));
DICTEntry privateFDEntry = fdEntries.get("Private");
if (privateFDEntry != null) {
newFontDict = setFDData(privateFDEntry, newFontDict);
}

fdFonts.add(newFontDict);
}
}
}
return fdFonts;
}

private FontDict setFDData(DICTEntry privateFDEntry, FontDict newFontDict) throws IOException {
int privateFDLength = privateFDEntry.getOperands().get(0).intValue();
int privateFDOffset = privateFDEntry.getOperands().get(1).intValue();
cffData.setPosition(privateFDOffset);
byte[] privateDict = cffData.readBytes(privateFDLength);
newFontDict.setPrivateDictData(privateFDOffset, privateFDLength);
LinkedHashMap<String, DICTEntry> privateEntries = parseDictData(privateDict);
DICTEntry subroutines = privateEntries.get("Subrs");
if (subroutines != null) {
CFFIndexData localSubrs = readIndex(privateFDOffset
+ subroutines.getOperands().get(0).intValue());
newFontDict.setLocalSubrData(localSubrs);
} else {
newFontDict.setLocalSubrData(new CFFIndexData());
}
return newFontDict;
}

private String getString(int sid) throws IOException {
return new String(stringIndex.getValue(sid - NUM_STANDARD_STRINGS));
}

private CFFIndexData readLocalIndexSubrs() throws IOException {
CFFIndexData localSubrs = null;
DICTEntry privateEntry = topDict.get("Private");
if (privateEntry != null) {
int length = privateEntry.getOperands().get(0).intValue();
int offset = privateEntry.getOperands().get(1).intValue();
cffData.setPosition(offset);
byte[] privateData = cffData.readBytes(length);
LinkedHashMap<String, DICTEntry> privateDict = parseDictData(privateData);
DICTEntry localSubrsEntry = privateDict.get("Subrs");
if (localSubrsEntry != null) {
int localOffset = offset + localSubrsEntry.getOperands().get(0).intValue();
cffData.setPosition(localOffset);
localSubrs = readIndex();
}
}
return localSubrs;
}

/**
* Parent class which provides the ability to retrieve byte data from
* a sub-table.
*/
public class CFFSubTable {
private DataLocation dataLocation = new DataLocation();

public void setByteData(int position, int length) {
dataLocation = new DataLocation(position, length);
}

public byte[] getByteData() throws IOException {
int oldPos = cffData.getPosition();
try {
cffData.setPosition(dataLocation.getDataPosition());
return cffData.readBytes(dataLocation.getDataLength());
} finally {
cffData.setPosition(oldPos);
}
}
}

/**
* An object used to hold index data from the CFF data
*/
public class CFFIndexData extends CFFSubTable {
private int numObjects;
private int offSize;
private int[] offsets = new int[0];
private DataLocation dataLocation = new DataLocation();

public void setNumObjects(int numObjects) {
this.numObjects = numObjects;
}

public int getNumObjects() {
return this.numObjects;
}

public void setOffSize(int offSize) {
this.offSize = offSize;
}

public int getOffSize() {
return this.offSize;
}

public void setOffsets(int[] offsets) {
this.offsets = offsets.clone();
}

public int[] getOffsets() {
return offsets.clone();
}

public void setData(int position, int length) {
dataLocation = new DataLocation(position, length);
}

public byte[] getData() throws IOException {
int origPos = cffData.getPosition();
try {
cffData.setPosition(dataLocation.getDataPosition());
return cffData.readBytes(dataLocation.getDataLength());
} finally {
cffData.setPosition(origPos);
}
}

/**
* Parses index data from an index object found within the CFF byte data
* @param cffData A byte array containing the CFF data
* @throws IOException Throws an IO Exception if an error occurs
*/
public void parseIndexHeader(CFFDataInput cffData) throws IOException {
setNumObjects(cffData.readCard16());
setOffSize(cffData.readOffSize());
int[] offsets = new int[getNumObjects() + 1];
byte[] bytes;
//Fills the offsets array
for (int i = 0; i <= getNumObjects(); i++) {
switch (getOffSize()) {
case 1:
offsets[i] = cffData.readCard8();
break;
case 2:
offsets[i] = cffData.readCard16();
break;
case 3:
bytes = cffData.readBytes(3);
offsets[i] = ((bytes[0] & 0xFF) << 16) + ((bytes[1] & 0xFF) << 8) + (bytes[2] & 0xFF);
break;
case 4:
bytes = cffData.readBytes(4);
offsets[i] = ((bytes[0] & 0xFF) << 24) + ((bytes[1] & 0xFF) << 16)
+ ((bytes[2] & 0xFF) << 8) + (bytes[3] & 0xFF);
break;
default: continue;
}
}
setOffsets(offsets);
int position = cffData.getPosition();
int dataSize = offsets[offsets.length - 1] - offsets[0];

cffData.setPosition(cffData.getPosition() + dataSize);
setData(position, dataSize);
}

/**
* Retrieves data from the index data
* @param index The index position of the data to retrieve
* @return Returns the byte data for the given index
* @throws IOException Throws an IO Exception if an error occurs
*/
public byte[] getValue(int index) throws IOException {
int oldPos = cffData.getPosition();
try {
cffData.setPosition(dataLocation.getDataPosition() + (offsets[index] - 1));
return cffData.readBytes(offsets[index + 1] - offsets[index]);
} finally {
cffData.setPosition(oldPos);
}
}

public int getValuePosition(int index) {
return dataLocation.getDataPosition() + (offsets[index] - 1);
}

public int getValueLength(int index) {
return offsets[index + 1] - offsets[index];
}
}

public abstract class CustomEncoding {
private int format;
private int numEntries;

public void setFormat(int format) {
this.format = format;
}

public int getFormat() {
return format;
}

public void setNumEntries(int numEntries) {
this.numEntries = numEntries;
}

public int getNumEntries() {
return numEntries;
}
}

public class Format0Encoding extends CustomEncoding {
private int[] codes = new int[0];

public void setCodes(int[] codes) {
this.codes = codes.clone();
}

public int[] getCodes() {
return codes.clone();
}
}

public class Format1Encoding extends CustomEncoding {
private LinkedHashMap<Integer, Integer> ranges;

public void setRanges(LinkedHashMap<Integer, Integer> ranges) {
this.ranges = ranges;
}

public LinkedHashMap<Integer, Integer> getRanges() {
return ranges;
}
}

public class FDSelect {
private int format;

public void setFormat(int format) {
this.format = format;
}

public int getFormat() {
return format;
}
}

public class Format0FDSelect extends FDSelect {
private int[] fds = new int[0];

public void setFDIndexes(int[] fds) {
this.fds = fds.clone();
}

public int[] getFDIndexes() {
return fds.clone();
}
}

public class Format3FDSelect extends FDSelect {
private int rangeCount;
private LinkedHashMap<Integer, Integer> ranges;
private int sentinelGID;

public void setRangeCount(int rangeCount) {
this.rangeCount = rangeCount;
}

public int getRangeCount() {
return rangeCount;
}

public void setRanges(LinkedHashMap<Integer, Integer> ranges) {
this.ranges = ranges;
}

public LinkedHashMap<Integer, Integer> getRanges() {
return ranges;
}

public void setSentinelGID(int sentinelGID) {
this.sentinelGID = sentinelGID;
}

public int getSentinelGID() {
return sentinelGID;
}
}

public class FontDict extends CFFSubTable {
private String fontName;
private DataLocation dataLocation = new DataLocation();
private CFFIndexData localSubrData;

public void setFontName(String groupName) {
this.fontName = groupName;
}

public String getFontName() {
return fontName;
}

public void setPrivateDictData(int position, int length) {
dataLocation = new DataLocation(position, length);
}

public byte[] getPrivateDictData() throws IOException {
int origPos = cffData.getPosition();
try {
cffData.setPosition(dataLocation.getDataPosition());
return cffData.readBytes(dataLocation.getDataLength());
} finally {
cffData.setPosition(origPos);
}
}

public void setLocalSubrData(CFFIndexData localSubrData) {
this.localSubrData = localSubrData;
}

public CFFIndexData getLocalSubrData() {
return localSubrData;
}
}

private static class DataLocation {
private int dataPosition;
private int dataLength;

public DataLocation() {
dataPosition = 0;
dataLength = 0;
}

public DataLocation(int position, int length) {
this.dataPosition = position;
this.dataLength = length;
}

public int getDataPosition() {
return dataPosition;
}

public int getDataLength() {
return dataLength;
}
}
}

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

@@ -31,7 +31,7 @@ import java.util.TreeSet;
*/
public class GlyfTable {

private final TTFMtxEntry[] mtxTab;
private final OFMtxEntry[] mtxTab;

private final long tableOffset;

@@ -47,7 +47,7 @@ public class GlyfTable {
/** All the glyphs that are composed, but do not appear in the subset. */
private Set<Integer> composedGlyphs = new TreeSet<Integer>();

GlyfTable(FontFileReader in, TTFMtxEntry[] metrics, TTFDirTabEntry dirTableEntry,
GlyfTable(FontFileReader in, OFMtxEntry[] metrics, OFDirTabEntry dirTableEntry,
Map<Integer, Integer> glyphs) throws IOException {
mtxTab = metrics;
tableOffset = dirTableEntry.getOffset();

src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java → src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java View File

@@ -26,17 +26,17 @@ import java.io.UnsupportedEncodingException;
/**
* This class represents an entry to a TrueType font's Dir Tab.
*/
public class TTFDirTabEntry {
public class OFDirTabEntry {

private byte[] tag = new byte[4];
private int checksum;
private long offset;
private long length;

public TTFDirTabEntry() {
public OFDirTabEntry() {
}

public TTFDirTabEntry(long offset, long length) {
public OFDirTabEntry(long offset, long length) {
this.offset = offset;
this.length = length;
}

src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java → src/java/org/apache/fop/fonts/truetype/OFFontLoader.java View File

@@ -38,13 +38,13 @@ import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.fonts.NamedCharacter;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;
import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion;
import org.apache.fop.util.HexEncoder;

/**
* Loads a TrueType font into memory directly from the original font file.
*/
public class TTFFontLoader extends FontLoader {
public class OFFontLoader extends FontLoader {

private MultiByteFont multiFont;
private SingleByteFont singleFont;
@@ -57,7 +57,7 @@ public class TTFFontLoader extends FontLoader {
* @param fontFileURI the URI representing the font file
* @param resourceResolver the resource resolver for font URI resolution
*/
public TTFFontLoader(URI fontFileURI, InternalResourceResolver resourceResolver) {
public OFFontLoader(URI fontFileURI, InternalResourceResolver resourceResolver) {
this(fontFileURI, null, true, EmbeddingMode.AUTO, EncodingMode.AUTO, true, true, resourceResolver);
}

@@ -73,7 +73,7 @@ public class TTFFontLoader extends FontLoader {
* @param useAdvanced true to enable loading advanced info if available, false to disable
* @param resolver the FontResolver for font URI resolution
*/
public TTFFontLoader(URI fontFileURI, String subFontName, boolean embedded,
public OFFontLoader(URI fontFileURI, String subFontName, boolean embedded,
EmbeddingMode embeddingMode, EncodingMode encodingMode, boolean useKerning,
boolean useAdvanced, InternalResourceResolver resolver) {
super(fontFileURI, embedded, useKerning, useAdvanced, resolver);
@@ -102,26 +102,30 @@ public class TTFFontLoader extends FontLoader {
private void read(String ttcFontName) throws IOException {
InputStream in = resourceResolver.getResource(this.fontFileURI);
try {
TTFFile ttf = new TTFFile(useKerning, useAdvanced);
FontFileReader reader = new FontFileReader(in);
boolean supported = ttf.readFont(reader, ttcFontName);
String header = readHeader(reader);
boolean isCFF = header.equals("OTTO");
OpenFont otf = (isCFF) ? new OTFFile() : new TTFFile(useKerning, useAdvanced);
boolean supported = otf.readFont(reader, header, ttcFontName);
if (!supported) {
throw new IOException("TrueType font is not supported: " + fontFileURI);
throw new IOException("The font does not have a Unicode cmap table: " + fontFileURI);
}
buildFont(ttf, ttcFontName);
buildFont(otf, ttcFontName);
loaded = true;
} finally {
IOUtils.closeQuietly(in);
}
}


private void buildFont(TTFFile ttf, String ttcFontName) {
if (ttf.isCFF()) {
throw new UnsupportedOperationException(
"OpenType fonts with CFF data are not supported, yet");
public static String readHeader(FontFileReader fontFile) throws IOException {
if (fontFile != null) {
fontFile.seekSet(0);
return fontFile.readTTFString(4); // TTF_FIXED_SIZE (4 bytes)
}
return null;
}

private void buildFont(OpenFont otf, String ttcFontName) {
boolean isCid = this.embedded;
if (this.encodingMode == EncodingMode.SINGLE_BYTE) {
isCid = false;
@@ -129,6 +133,7 @@ public class TTFFontLoader extends FontLoader {

if (isCid) {
multiFont = new MultiByteFont(resourceResolver, embeddingMode);
multiFont.setIsOTFFile(otf instanceof OTFFile);
returnFont = multiFont;
multiFont.setTTCName(ttcFontName);
} else {
@@ -136,47 +141,51 @@ public class TTFFontLoader extends FontLoader {
returnFont = singleFont;
}

returnFont.setFontName(ttf.getPostScriptName());
returnFont.setFullName(ttf.getFullName());
returnFont.setFamilyNames(ttf.getFamilyNames());
returnFont.setFontSubFamilyName(ttf.getSubFamilyName());
returnFont.setCapHeight(ttf.getCapHeight());
returnFont.setXHeight(ttf.getXHeight());
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()));
returnFont.setFontName(otf.getPostScriptName());
returnFont.setFullName(otf.getFullName());
returnFont.setFamilyNames(otf.getFamilyNames());
returnFont.setFontSubFamilyName(otf.getSubFamilyName());
returnFont.setCapHeight(otf.getCapHeight());
returnFont.setXHeight(otf.getXHeight());
returnFont.setAscender(otf.getLowerCaseAscent());
returnFont.setDescender(otf.getLowerCaseDescent());
returnFont.setFontBBox(otf.getFontBBox());
returnFont.setUnderlinePosition(otf.getUnderlinePosition() - otf.getUnderlineThickness() / 2);
returnFont.setUnderlineThickness(otf.getUnderlineThickness());
returnFont.setStrikeoutPosition(otf.getStrikeoutPosition() - otf.getStrikeoutThickness() / 2);
returnFont.setStrikeoutThickness(otf.getStrikeoutThickness());
returnFont.setFlags(otf.getFlags());
returnFont.setStemV(Integer.parseInt(otf.getStemV())); //not used for TTF
returnFont.setItalicAngle(Integer.parseInt(otf.getItalicAngle()));
returnFont.setMissingWidth(0);
returnFont.setWeight(ttf.getWeightClass());
returnFont.setWeight(otf.getWeightClass());
returnFont.setEmbeddingMode(this.embeddingMode);
if (isCid) {
multiFont.setCIDType(CIDFontType.CIDTYPE2);
multiFont.setWidthArray(ttf.getWidths());
multiFont.setBBoxArray(ttf.getBoundingBoxes());
if (otf instanceof OTFFile) {
multiFont.setCIDType(CIDFontType.CIDTYPE0);
} else {
multiFont.setCIDType(CIDFontType.CIDTYPE2);
}
multiFont.setWidthArray(otf.getWidths());
multiFont.setBBoxArray(otf.getBoundingBoxes());
} else {
singleFont.setFontType(FontType.TRUETYPE);
singleFont.setEncoding(ttf.getCharSetName());
returnFont.setFirstChar(ttf.getFirstChar());
returnFont.setLastChar(ttf.getLastChar());
singleFont.setTrueTypePostScriptVersion(ttf.getPostScriptVersion());
copyGlyphMetricsSingleByte(ttf);
singleFont.setEncoding(otf.getCharSetName());
returnFont.setFirstChar(otf.getFirstChar());
returnFont.setLastChar(otf.getLastChar());
singleFont.setTrueTypePostScriptVersion(otf.getPostScriptVersion());
copyGlyphMetricsSingleByte(otf);
}
returnFont.setCMap(getCMap(ttf));
returnFont.setCMap(getCMap(otf));

if (useKerning) {
copyKerning(ttf, isCid);
if (otf.getKerning() != null && useKerning) {
copyKerning(otf, isCid);
}
if (useAdvanced) {
copyAdvanced(ttf);
copyAdvanced(otf);
}
if (this.embedded) {
if (ttf.isEmbeddable()) {
if (otf.isEmbeddable()) {
returnFont.setEmbedURI(this.fontFileURI);
} else {
String msg = "The font " + this.fontFileURI + " is not embeddable due to a"
@@ -186,28 +195,29 @@ public class TTFFontLoader extends FontLoader {
}
}

private CMapSegment[] getCMap(TTFFile ttf) {
CMapSegment[] array = new CMapSegment[ttf.getCMaps().size()];
return ttf.getCMaps().toArray(array);
private CMapSegment[] getCMap(OpenFont otf) {
CMapSegment[] array = new CMapSegment[otf.getCMaps().size()];
return otf.getCMaps().toArray(array);
}

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

for (CMapSegment segment : otf.getCMaps()) {
if (segment.getUnicodeStart() < 0xFFFE) {
for (char u = (char)segment.getUnicodeStart(); u <= segment.getUnicodeEnd(); u++) {
int codePoint = singleFont.getEncoding().mapChar(u);
if (codePoint <= 0) {
int glyphIndex = segment.getGlyphStartIndex() + u - segment.getUnicodeStart();
String glyphName = ttf.getGlyphName(glyphIndex);
if (glyphName.length() == 0 && ttf.getPostScriptVersion() != PostScriptVersion.V2) {
String glyphName = otf.getGlyphName(glyphIndex);
if (glyphName.length() == 0 && otf.getPostScriptVersion() != PostScriptVersion.V2) {
glyphName = "u" + HexEncoder.encode(u);
}
if (glyphName.length() > 0) {
@@ -224,22 +234,22 @@ public class TTFFontLoader extends FontLoader {
/**
* Copy kerning information.
*/
private void copyKerning(TTFFile ttf, boolean isCid) {
private void copyKerning(OpenFont otf, boolean isCid) {

// Get kerning
Set<Integer> kerningSet;
if (isCid) {
kerningSet = ttf.getKerning().keySet();
kerningSet = otf.getKerning().keySet();
} else {
kerningSet = ttf.getAnsiKerning().keySet();
kerningSet = otf.getAnsiKerning().keySet();
}

for (Integer kpx1 : kerningSet) {
Map<Integer, Integer> h2;
if (isCid) {
h2 = ttf.getKerning().get(kpx1);
h2 = otf.getKerning().get(kpx1);
} else {
h2 = ttf.getAnsiKerning().get(kpx1);
h2 = otf.getAnsiKerning().get(kpx1);
}
returnFont.putKerningEntry(kpx1, h2);
}
@@ -248,12 +258,12 @@ public class TTFFontLoader extends FontLoader {
/**
* Copy advanced typographic information.
*/
private void copyAdvanced(TTFFile ttf) {
private void copyAdvanced(OpenFont otf) {
if (returnFont instanceof MultiByteFont) {
MultiByteFont mbf = (MultiByteFont) returnFont;
mbf.setGDEF(ttf.getGDEF());
mbf.setGSUB(ttf.getGSUB());
mbf.setGPOS(ttf.getGPOS());
mbf.setGDEF(otf.getGDEF());
mbf.setGSUB(otf.getGSUB());
mbf.setGPOS(otf.getGPOS());
}
}


src/java/org/apache/fop/fonts/truetype/TTFMtxEntry.java → src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java View File

@@ -24,7 +24,7 @@ import java.util.List;
/**
* This class represents a TrueType Mtx Entry.
*/
class TTFMtxEntry {
class OFMtxEntry {

private int wx;
private int lsb;

src/java/org/apache/fop/fonts/truetype/TTFTableName.java → src/java/org/apache/fop/fonts/truetype/OFTableName.java View File

@@ -24,98 +24,104 @@ package org.apache.fop.fonts.truetype;
* Represents table names as found in a TrueType font's Table Directory.
* TrueType fonts may have custom tables so we cannot use an enum.
*/
public final class TTFTableName {
public final class OFTableName {

/** The first table in a TrueType font file containing metadata about other tables. */
public static final TTFTableName TABLE_DIRECTORY = new TTFTableName("tableDirectory");
public static final OFTableName TABLE_DIRECTORY = new OFTableName("tableDirectory");

/** Baseline data */
public static final OFTableName BASE = new OFTableName("BASE");

/** CFF data/ */
public static final OFTableName CFF = new OFTableName("CFF ");

/** Embedded bitmap data. */
public static final TTFTableName EBDT = new TTFTableName("EBDT");
public static final OFTableName EBDT = new OFTableName("EBDT");

/** Embedded bitmap location data. */
public static final TTFTableName EBLC = new TTFTableName("EBLC");
public static final OFTableName EBLC = new OFTableName("EBLC");

/** Embedded bitmap scaling data. */
public static final TTFTableName EBSC = new TTFTableName("EBSC");
public static final OFTableName EBSC = new OFTableName("EBSC");

/** A FontForge specific table. */
public static final TTFTableName FFTM = new TTFTableName("FFTM");
public static final OFTableName FFTM = new OFTableName("FFTM");

/** Divides glyphs into various classes that make using the GPOS/GSUB tables easier. */
public static final TTFTableName GDEF = new TTFTableName("GDEF");
public static final OFTableName GDEF = new OFTableName("GDEF");

/** Provides kerning information, mark-to-base, etc. for opentype fonts. */
public static final TTFTableName GPOS = new TTFTableName("GPOS");
public static final OFTableName GPOS = new OFTableName("GPOS");

/** Provides ligature information, swash, etc. for opentype fonts. */
public static final TTFTableName GSUB = new TTFTableName("GSUB");
public static final OFTableName GSUB = new OFTableName("GSUB");

/** Linear threshold table. */
public static final TTFTableName LTSH = new TTFTableName("LTSH");
public static final OFTableName LTSH = new OFTableName("LTSH");

/** OS/2 and Windows specific metrics. */
public static final TTFTableName OS2 = new TTFTableName("OS/2");
public static final OFTableName OS2 = new OFTableName("OS/2");

/** PCL 5 data. */
public static final TTFTableName PCLT = new TTFTableName("PCLT");
public static final OFTableName PCLT = new OFTableName("PCLT");

/** Vertical Device Metrics table. */
public static final TTFTableName VDMX = new TTFTableName("VDMX");
public static final OFTableName VDMX = new OFTableName("VDMX");

/** Character to glyph mapping. */
public static final TTFTableName CMAP = new TTFTableName("cmap");
public static final OFTableName CMAP = new OFTableName("cmap");

/** Control Value Table. */
public static final TTFTableName CVT = new TTFTableName("cvt ");
public static final OFTableName CVT = new OFTableName("cvt ");

/** Font program. */
public static final TTFTableName FPGM = new TTFTableName("fpgm");
public static final OFTableName FPGM = new OFTableName("fpgm");

/** Grid-fitting and scan conversion procedure (grayscale). */
public static final TTFTableName GASP = new TTFTableName("gasp");
public static final OFTableName GASP = new OFTableName("gasp");

/** Glyph data. */
public static final TTFTableName GLYF = new TTFTableName("glyf");
public static final OFTableName GLYF = new OFTableName("glyf");

/** Horizontal device metrics. */
public static final TTFTableName HDMX = new TTFTableName("hdmx");
public static final OFTableName HDMX = new OFTableName("hdmx");

/** Font header. */
public static final TTFTableName HEAD = new TTFTableName("head");
public static final OFTableName HEAD = new OFTableName("head");

/** Horizontal header. */
public static final TTFTableName HHEA = new TTFTableName("hhea");
public static final OFTableName HHEA = new OFTableName("hhea");

/** Horizontal metrics. */
public static final TTFTableName HMTX = new TTFTableName("hmtx");
public static final OFTableName HMTX = new OFTableName("hmtx");

/** Kerning. */
public static final TTFTableName KERN = new TTFTableName("kern");
public static final OFTableName KERN = new OFTableName("kern");

/** Index to location. */
public static final TTFTableName LOCA = new TTFTableName("loca");
public static final OFTableName LOCA = new OFTableName("loca");

/** Maximum profile. */
public static final TTFTableName MAXP = new TTFTableName("maxp");
public static final OFTableName MAXP = new OFTableName("maxp");

/** Naming table. */
public static final TTFTableName NAME = new TTFTableName("name");
public static final OFTableName NAME = new OFTableName("name");

/** PostScript information. */
public static final TTFTableName POST = new TTFTableName("post");
public static final OFTableName POST = new OFTableName("post");

/** CVT Program. */
public static final TTFTableName PREP = new TTFTableName("prep");
public static final OFTableName PREP = new OFTableName("prep");

/** Vertical Metrics header. */
public static final TTFTableName VHEA = new TTFTableName("vhea");
public static final OFTableName VHEA = new OFTableName("vhea");

/** Vertical Metrics. */
public static final TTFTableName VMTX = new TTFTableName("vmtx");
public static final OFTableName VMTX = new OFTableName("vmtx");

private final String name;

private TTFTableName(String name) {
private OFTableName(String name) {
this.name = name;
}

@@ -131,9 +137,9 @@ public final class TTFTableName {
* @param tableName table name as in the Table Directory
* @return TTFTableName
*/
public static TTFTableName getValue(String tableName) {
public static OFTableName getValue(String tableName) {
if (tableName != null) {
return new TTFTableName(tableName);
return new OFTableName(tableName);
}
throw new IllegalArgumentException("A TrueType font table name must not be null");
}
@@ -148,10 +154,10 @@ public final class TTFTableName {
if (o == this) {
return true;
}
if (!(o instanceof TTFTableName)) {
if (!(o instanceof OFTableName)) {
return false;
}
TTFTableName to = (TTFTableName) o;
OFTableName to = (OFTableName) o;
return this.name.equals(to.getName());
}


+ 109
- 0
src/java/org/apache/fop/fonts/truetype/OTFFile.java View File

@@ -0,0 +1,109 @@
/*
* 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.truetype;

import java.io.IOException;

import org.apache.fontbox.cff.CFFDataInput;
import org.apache.fontbox.cff.CFFFont;
import org.apache.fontbox.cff.CFFFont.Mapping;
import org.apache.fontbox.cff.CFFParser;

public class OTFFile extends OpenFont {

protected CFFFont fileFont;

public OTFFile() throws IOException {
checkForFontbox();
}

private void checkForFontbox() throws IOException {
try {
Class.forName("org.apache.fontbox.cff.CFFFont");
} catch (ClassNotFoundException ex) {
throw new IOException("The Fontbox jar was not found in the classpath. This is "
+ "required for OTF CFF ssupport.");
}
}

@Override
protected void updateBBoxAndOffset() throws IOException {
UnicodeMapping[] mappings = unicodeMappings.toArray(new UnicodeMapping[0]);
for (int i = 0; i < mappings.length; i++) {
int glyphIdx = mappings[i].getGlyphIndex();
Mapping m = fileFont.getGIDMappings().get(glyphIdx);
int[] bbox = fileFont.getBoundingBox(m.getSID());
String name = fileFont.getNameOfCharFromCode(m.getSID());
mtxTab[glyphIdx].setBoundingBox(bbox);
mtxTab[glyphIdx].setName(name);
}
}

@Override
protected void initializeFont(FontFileReader in) throws IOException {
fontFile = in;
fontFile.seekSet(0);
CFFParser parser = new CFFParser();
fileFont = parser.parse(in.getAllBytes()).get(0);
}

protected void readName() throws IOException {
Object familyName = fileFont.getProperty("FamilyName");
if (familyName != null && !familyName.equals("")) {
familyNames.add(familyName.toString());
fullName = familyName.toString();
} else {
fullName = fileFont.getName();
familyNames.add(fullName);
}
}

/**
* Reads the CFFData from a given font file
* @param fontFile The font file being read
* @return The byte data found in the CFF table
*/
public static byte[] getCFFData(FontFileReader fontFile) throws IOException {
byte[] cff = new byte[0];
CFFDataInput input = new CFFDataInput(fontFile.getAllBytes());
input.readBytes(4); //OTTO
short numTables = input.readShort();
input.readShort(); //searchRange
input.readShort(); //entrySelector
input.readShort(); //rangeShift

for (int q = 0; q < numTables; q++) {
String tagName = new String(input.readBytes(4));
readLong(input); //Checksum
long offset = readLong(input);
long length = readLong(input);
if (tagName.equals("CFF ")) {
cff = new byte[(int)length];
System.arraycopy(fontFile.getAllBytes(), (int)offset, cff, 0, cff.length);
break;
}
}
return cff;
}

private static long readLong(CFFDataInput input) throws IOException {
return (input.readCard16() << 16) | input.readCard16();
}
}

+ 1097
- 0
src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
File diff suppressed because it is too large
View File


+ 1971
- 0
src/java/org/apache/fop/fonts/truetype/OpenFont.java
File diff suppressed because it is too large
View File


+ 74
- 1971
src/java/org/apache/fop/fonts/truetype/TTFFile.java
File diff suppressed because it is too large
View File


+ 53
- 53
src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java View File

@@ -43,7 +43,7 @@ public class TTFSubSetFile extends TTFFile {
* Offsets in name table to be filled out by table.
* The offsets are to the checkSum field
*/
private Map<TTFTableName, Integer> offsets = new HashMap<TTFTableName, Integer>();
private Map<OFTableName, Integer> offsets = new HashMap<OFTableName, Integer>();

private int checkSumAdjustmentOffset = 0;
private int locaOffset = 0;
@@ -67,8 +67,8 @@ public class TTFSubSetFile extends TTFFile {
}

/** The dir tab entries in the new subset font. */
private Map<TTFTableName, TTFDirTabEntry> newDirTabs
= new HashMap<TTFTableName, TTFDirTabEntry>();
private Map<OFTableName, OFDirTabEntry> newDirTabs
= new HashMap<OFTableName, OFDirTabEntry>();

private int determineTableCount() {
int numTables = 4; //4 req'd tables: head,hhea,hmtx,maxp
@@ -117,29 +117,29 @@ public class TTFSubSetFile extends TTFFile {
writeUShort((numTables * 16) - searchRange);
realSize += 2;
// Create space for the table entries (these must be in ASCII alphabetical order[A-Z] then[a-z])
writeTableName(TTFTableName.OS2);
writeTableName(OFTableName.OS2);

if (hasCvt()) {
writeTableName(TTFTableName.CVT);
writeTableName(OFTableName.CVT);
}
if (hasFpgm()) {
writeTableName(TTFTableName.FPGM);
writeTableName(OFTableName.FPGM);
}
writeTableName(TTFTableName.GLYF);
writeTableName(TTFTableName.HEAD);
writeTableName(TTFTableName.HHEA);
writeTableName(TTFTableName.HMTX);
writeTableName(TTFTableName.LOCA);
writeTableName(TTFTableName.MAXP);
writeTableName(TTFTableName.NAME);
writeTableName(TTFTableName.POST);
writeTableName(OFTableName.GLYF);
writeTableName(OFTableName.HEAD);
writeTableName(OFTableName.HHEA);
writeTableName(OFTableName.HMTX);
writeTableName(OFTableName.LOCA);
writeTableName(OFTableName.MAXP);
writeTableName(OFTableName.NAME);
writeTableName(OFTableName.POST);
if (hasPrep()) {
writeTableName(TTFTableName.PREP);
writeTableName(OFTableName.PREP);
}
newDirTabs.put(TTFTableName.TABLE_DIRECTORY, new TTFDirTabEntry(0, currentPos));
newDirTabs.put(OFTableName.TABLE_DIRECTORY, new OFDirTabEntry(0, currentPos));
}

private void writeTableName(TTFTableName tableName) {
private void writeTableName(OFTableName tableName) {
writeString(tableName.getName());
offsets.put(tableName, currentPos);
currentPos += 12;
@@ -148,15 +148,15 @@ public class TTFSubSetFile extends TTFFile {


private boolean hasCvt() {
return dirTabs.containsKey(TTFTableName.CVT);
return dirTabs.containsKey(OFTableName.CVT);
}

private boolean hasFpgm() {
return dirTabs.containsKey(TTFTableName.FPGM);
return dirTabs.containsKey(OFTableName.FPGM);
}

private boolean hasPrep() {
return dirTabs.containsKey(TTFTableName.PREP);
return dirTabs.containsKey(OFTableName.PREP);
}

/**
@@ -165,15 +165,15 @@ public class TTFSubSetFile extends TTFFile {
private void createLoca(int size) throws IOException {
pad4();
locaOffset = currentPos;
int dirTableOffset = offsets.get(TTFTableName.LOCA);
int dirTableOffset = offsets.get(OFTableName.LOCA);
writeULong(dirTableOffset + 4, currentPos);
writeULong(dirTableOffset + 8, size * 4 + 4);
currentPos += size * 4 + 4;
realSize += size * 4 + 4;
}

private boolean copyTable(FontFileReader in, TTFTableName tableName) throws IOException {
TTFDirTabEntry entry = dirTabs.get(tableName);
private boolean copyTable(FontFileReader in, OFTableName tableName) throws IOException {
OFDirTabEntry entry = dirTabs.get(tableName);
if (entry != null) {
pad4();
seekTab(in, tableName, 0);
@@ -193,28 +193,28 @@ public class TTFSubSetFile extends TTFFile {
* Copy the cvt table as is from original font to subset font
*/
private boolean createCvt(FontFileReader in) throws IOException {
return copyTable(in, TTFTableName.CVT);
return copyTable(in, OFTableName.CVT);
}

/**
* Copy the fpgm table as is from original font to subset font
*/
private boolean createFpgm(FontFileReader in) throws IOException {
return copyTable(in, TTFTableName.FPGM);
return copyTable(in, OFTableName.FPGM);
}

/**
* Copy the name table as is from the original.
*/
private boolean createName(FontFileReader in) throws IOException {
return copyTable(in, TTFTableName.NAME);
return copyTable(in, OFTableName.NAME);
}

/**
* Copy the OS/2 table as is from the original.
*/
private boolean createOS2(FontFileReader in) throws IOException {
return copyTable(in, TTFTableName.OS2);
return copyTable(in, OFTableName.OS2);
}

/**
@@ -222,8 +222,8 @@ public class TTFSubSetFile extends TTFFile {
* and set num glyphs to size
*/
private void createMaxp(FontFileReader in, int size) throws IOException {
TTFTableName maxp = TTFTableName.MAXP;
TTFDirTabEntry entry = dirTabs.get(maxp);
OFTableName maxp = OFTableName.MAXP;
OFDirTabEntry entry = dirTabs.get(maxp);
if (entry != null) {
pad4();
seekTab(in, maxp, 0);
@@ -240,8 +240,8 @@ public class TTFSubSetFile extends TTFFile {
}

private void createPost(FontFileReader in) throws IOException {
TTFTableName post = TTFTableName.POST;
TTFDirTabEntry entry = dirTabs.get(post);
OFTableName post = OFTableName.POST;
OFDirTabEntry entry = dirTabs.get(post);
if (entry != null) {
pad4();
seekTab(in, post, 0);
@@ -266,7 +266,7 @@ public class TTFSubSetFile extends TTFFile {
* Copy the prep table as is from original font to subset font
*/
private boolean createPrep(FontFileReader in) throws IOException {
return copyTable(in, TTFTableName.PREP);
return copyTable(in, OFTableName.PREP);
}


@@ -275,15 +275,15 @@ public class TTFSubSetFile extends TTFFile {
* and fill in size of hmtx table
*/
private void createHhea(FontFileReader in, int size) throws IOException {
TTFDirTabEntry entry = dirTabs.get(TTFTableName.HHEA);
OFDirTabEntry entry = dirTabs.get(OFTableName.HHEA);
if (entry != null) {
pad4();
seekTab(in, TTFTableName.HHEA, 0);
seekTab(in, OFTableName.HHEA, 0);
System.arraycopy(in.getBytes((int) entry.getOffset(), (int) entry.getLength()), 0,
output, currentPos, (int) entry.getLength());
writeUShort((int) entry.getLength() + currentPos - 2, size);

updateCheckSum(currentPos, (int) entry.getLength(), TTFTableName.HHEA);
updateCheckSum(currentPos, (int) entry.getLength(), OFTableName.HHEA);
currentPos += (int) entry.getLength();
realSize += (int) entry.getLength();
} else {
@@ -299,8 +299,8 @@ public class TTFSubSetFile extends TTFFile {
* in checkSumAdjustmentOffset
*/
private void createHead(FontFileReader in) throws IOException {
TTFTableName head = TTFTableName.HEAD;
TTFDirTabEntry entry = dirTabs.get(head);
OFTableName head = OFTableName.HEAD;
OFDirTabEntry entry = dirTabs.get(head);
if (entry != null) {
pad4();
seekTab(in, head, 0);
@@ -329,8 +329,8 @@ public class TTFSubSetFile extends TTFFile {
*/
private void createGlyf(FontFileReader in,
Map<Integer, Integer> glyphs) throws IOException {
TTFTableName glyf = TTFTableName.GLYF;
TTFDirTabEntry entry = dirTabs.get(glyf);
OFTableName glyf = OFTableName.GLYF;
OFDirTabEntry entry = dirTabs.get(glyf);
int size = 0;
int startPos = 0;
int endOffset = 0; // Store this as the last loca
@@ -393,10 +393,10 @@ public class TTFSubSetFile extends TTFFile {
writeULong(locaOffset + glyphs.size() * 4, endOffset);
int locaSize = glyphs.size() * 4 + 4;
int checksum = getCheckSum(output, locaOffset, locaSize);
writeULong(offsets.get(TTFTableName.LOCA), checksum);
writeULong(offsets.get(OFTableName.LOCA), checksum);
int padSize = (locaOffset + locaSize) % 4;
newDirTabs.put(TTFTableName.LOCA,
new TTFDirTabEntry(locaOffset, locaSize + padSize));
newDirTabs.put(OFTableName.LOCA,
new OFDirTabEntry(locaOffset, locaSize + padSize));
} else {
throw new IOException("Can't find glyf table");
}
@@ -420,8 +420,8 @@ public class TTFSubSetFile extends TTFFile {
*/
private void createHmtx(FontFileReader in,
Map<Integer, Integer> glyphs) throws IOException {
TTFTableName hmtx = TTFTableName.HMTX;
TTFDirTabEntry entry = dirTabs.get(hmtx);
OFTableName hmtx = OFTableName.HMTX;
OFDirTabEntry entry = dirTabs.get(hmtx);

int longHorMetricSize = glyphs.size() * 2;
int leftSideBearingSize = glyphs.size() * 2;
@@ -457,11 +457,11 @@ public class TTFSubSetFile extends TTFFile {
* new index as (Integer) value)
* @throws IOException in case of an I/O problem
*/
public void readFont(FontFileReader in, String name,
public void readFont(FontFileReader in, String name, String header,
Map<Integer, Integer> glyphs) throws IOException {
fontFile = in;
//Check if TrueType collection, and that the name exists in the collection
if (!checkTTC(name)) {
if (!checkTTC(header, name)) {
throw new IOException("Failed to read font");
}

@@ -533,7 +533,7 @@ public class TTFSubSetFile extends TTFFile {
glyphOffsets[i + 1] - glyphOffsets[i]);
}
// Stream the last glyph
TTFDirTabEntry glyf = newDirTabs.get(TTFTableName.GLYF);
OFDirTabEntry glyf = newDirTabs.get(OFTableName.GLYF);
long lastGlyphLength = glyf.getLength()
- (glyphOffsets[glyphOffsets.length - 1] - glyf.getOffset());
glyphOut.streamGlyph(output, glyphOffsets[glyphOffsets.length - 1],
@@ -543,14 +543,14 @@ public class TTFSubSetFile extends TTFFile {

@Override
public void stream(TTFOutputStream ttfOut) throws IOException {
SortedSet<Map.Entry<TTFTableName, TTFDirTabEntry>> sortedDirTabs
SortedSet<Map.Entry<OFTableName, OFDirTabEntry>> sortedDirTabs
= sortDirTabMap(newDirTabs);
TTFTableOutputStream tableOut = ttfOut.getTableOutputStream();
TTFGlyphOutputStream glyphOut = ttfOut.getGlyphOutputStream();

ttfOut.startFontStream();
for (Map.Entry<TTFTableName, TTFDirTabEntry> entry : sortedDirTabs) {
if (entry.getKey().equals(TTFTableName.GLYF)) {
for (Map.Entry<OFTableName, OFDirTabEntry> entry : sortedDirTabs) {
if (entry.getKey().equals(OFTableName.GLYF)) {
handleGlyphSubset(glyphOut);
} else {
tableOut.streamTable(output, (int) entry.getValue().getOffset(),
@@ -562,7 +562,7 @@ public class TTFSubSetFile extends TTFFile {

private void scanGlyphs(FontFileReader in, Map<Integer, Integer> subsetGlyphs)
throws IOException {
TTFDirTabEntry glyfTableInfo = dirTabs.get(TTFTableName.GLYF);
OFDirTabEntry glyfTableInfo = dirTabs.get(OFTableName.GLYF);
if (glyfTableInfo == null) {
throw new IOException("Glyf table could not be found");
}
@@ -663,11 +663,11 @@ public class TTFSubSetFile extends TTFFile {
}


private void updateCheckSum(int tableStart, int tableSize, TTFTableName tableName) {
private void updateCheckSum(int tableStart, int tableSize, OFTableName tableName) {
int checksum = getCheckSum(output, tableStart, tableSize);
int offset = offsets.get(tableName);
int padSize = getPadSize(tableStart + tableSize);
newDirTabs.put(tableName, new TTFDirTabEntry(tableStart, tableSize + padSize));
newDirTabs.put(tableName, new OFDirTabEntry(tableStart, tableSize + padSize));
writeULong(offset, checksum);
writeULong(offset + 4, tableStart);
writeULong(offset + 8, tableSize);

+ 1
- 1
src/java/org/apache/fop/fonts/type1/AFMFile.java View File

@@ -319,7 +319,7 @@ public class AFMFile {
*/
public void addCharMetrics(AFMCharMetrics metrics) {
String name = metrics.getCharName();
if (metrics.getUnicodeSequence() == null) {
if (metrics.getUnicodeSequence() == null && name.equals(".notdef")) {
//Ignore as no Unicode assignment is possible
return;
}

+ 6
- 3
src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java View File

@@ -28,6 +28,8 @@ import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xmlgraphics.fonts.Glyphs;

import org.apache.fop.fonts.NamedCharacter;
import org.apache.fop.fonts.type1.AFMParser.ValueHandler;

@@ -102,9 +104,10 @@ abstract class CharMetricsHandler {
AFMCharMetrics chm = defaultHandler.parse(line, stack, afmFileName);
NamedCharacter namedChar = chm.getCharacter();
if (namedChar != null) {
int codePoint = AdobeStandardEncoding.getAdobeCodePoint(namedChar.getName());
if (chm.getCharCode() != codePoint) {
LOG.info(afmFileName + ": named character '" + namedChar.getName() + "'"
String charName = namedChar.getName();
int codePoint = AdobeStandardEncoding.getAdobeCodePoint(charName);
if (chm.getCharCode() != codePoint && !Glyphs.NOTDEF.equals(charName)) {
LOG.info(afmFileName + ": named character '" + charName + "'"
+ " has an incorrect code point: " + chm.getCharCode()
+ ". Changed to " + codePoint);
chm.setCharCode(codePoint);

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

@@ -173,7 +173,21 @@ public class Type1FontLoader extends FontLoader {
addUnencodedBasedOnAFM(afm);
}
} else {
if (pfm.getCharSet() >= 0 && pfm.getCharSet() <= 2) {
if (pfm.getCharSet() == 2 && !pfm.getCharSetName().equals("Symbol")) {
int[] table = new int[256];
String[] charNameMap = new String[256];
int j = 0;
for (int i = pfm.getFirstChar(); i < pfm.getLastChar(); i++) {
if (j < table.length) {
table[j] = i;
table[j + 1] = i;
j += 2;
}
charNameMap[i] = String.format("x%03o", i);
}
CodePointMapping mapping = new CodePointMapping("custom", table, charNameMap);
singleFont.setEncoding(mapping);
} else if (pfm.getCharSet() >= 0 && pfm.getCharSet() <= 2) {
singleFont.setEncoding(pfm.getCharSetName() + "Encoding");
} else {
log.warn("The PFM reports an unsupported encoding ("
@@ -400,10 +414,7 @@ public class Type1FontLoader extends FontLoader {
List<AFMCharMetrics> chars = afm.getCharMetrics();
for (AFMCharMetrics charMetrics : chars) {
if (charMetrics.getCharCode() >= 0) {
String u = charMetrics.getUnicodeSequence();
if (u != null && u.length() == 1) {
mappingCount++;
}
mappingCount++;
}
}
// ...and now build the table.
@@ -416,6 +427,10 @@ public class Type1FontLoader extends FontLoader {
String unicodes = charMetrics.getUnicodeSequence();
if (unicodes == null) {
log.info("No Unicode mapping for glyph: " + charMetrics);
table[idx] = charMetrics.getCharCode();
idx++;
table[idx] = charMetrics.getCharCode();
idx++;
} else if (unicodes.length() == 1) {
table[idx] = charMetrics.getCharCode();
idx++;

+ 0
- 3
src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java View File

@@ -65,9 +65,6 @@ public abstract class AbstractBaseLayoutManager
public AbstractBaseLayoutManager(FObj fo) {
this.fobj = fo;
setGeneratesReferenceArea(fo.generatesReferenceAreas());
if (getGeneratesReferenceArea()) {
setGeneratesBlockArea(true);
}
}

// --------- Property Resolution related functions --------- //

+ 28
- 0
src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java View File

@@ -342,6 +342,34 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager im
&& isFinished());
}

public boolean hasLineAreaDescendant() {
if (childLMs == null || childLMs.isEmpty()) {
return false;
} else {
for (LayoutManager childLM : childLMs) {
if (childLM.hasLineAreaDescendant()) {
return true;
}
}
}
return false;
}

public int getBaselineOffset() {
if (childLMs != null) {
for (LayoutManager childLM : childLMs) {
if (childLM.hasLineAreaDescendant()) {
return childLM.getBaselineOffset();
}
}
}
throw newNoLineAreaDescendantException();
}

protected IllegalStateException newNoLineAreaDescendantException() {
return new IllegalStateException("getBaselineOffset called on an object that has no line-area descendant");
}

/**
* Transfers foreign attributes from the formatting object to the area.
* @param targetArea the area to set the attributes on

+ 12
- 12
src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java View File

@@ -33,11 +33,11 @@ public final class AreaAdditionUtil {

/**
* Creates the child areas for the given layout manager.
* @param bslm the BlockStackingLayoutManager instance for which "addAreas" is performed.
* @param parentLM the parent layout manager
* @param parentIter the position iterator
* @param layoutContext the layout context
*/
public static void addAreas(BlockStackingLayoutManager bslm,
public static void addAreas(AbstractLayoutManager parentLM,
PositionIterator parentIter, LayoutContext layoutContext) {
LayoutManager childLM;
LayoutContext lc = LayoutContext.offspringOf(layoutContext);
@@ -46,8 +46,8 @@ public final class AreaAdditionUtil {
Position firstPos = null;
Position lastPos = null;

if (bslm != null) {
bslm.addId();
if (parentLM != null) {
parentLM.addId();
}

// "unwrap" the NonLeafPositions stored in parentIter
@@ -86,11 +86,11 @@ public final class AreaAdditionUtil {
//doesn't give us that info.
}

if (bslm != null) {
bslm.registerMarkers(
if (parentLM != null) {
parentLM.registerMarkers(
true,
bslm.isFirst(firstPos),
bslm.isLast(lastPos));
parentLM.isFirst(firstPos),
parentLM.isLast(lastPos));
}

PositionIterator childPosIter = new PositionIterator(positionList.listIterator());
@@ -113,11 +113,11 @@ public final class AreaAdditionUtil {
childLM.addAreas(childPosIter, lc);
}

if (bslm != null) {
bslm.registerMarkers(
if (parentLM != null) {
parentLM.registerMarkers(
false,
bslm.isFirst(firstPos),
bslm.isLast(lastPos));
parentLM.isFirst(firstPos),
parentLM.isLast(lastPos));
}



+ 10
- 54
src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java View File

@@ -37,6 +37,7 @@ import org.apache.fop.datatypes.FODimension;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.flow.BlockContainer;
import org.apache.fop.fo.properties.CommonAbsolutePosition;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.SpaceVal;
@@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal;
/**
* LayoutManager for a block-container FO.
*/
public class BlockContainerLayoutManager extends BlockStackingLayoutManager implements
ConditionalElementListener, BreakOpportunity {
public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
implements BreakOpportunity {

/**
* logging instance
@@ -79,13 +80,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
private MinOptMax foBlockSpaceBefore;
private MinOptMax foBlockSpaceAfter;

private boolean discardBorderBefore;
private boolean discardBorderAfter;
private boolean discardPaddingBefore;
private boolean discardPaddingAfter;
private MinOptMax effSpaceBefore;
private MinOptMax effSpaceAfter;

private int horizontalOverflow;
private double contentRectOffsetX = 0;
private double contentRectOffsetY = 0;
@@ -96,6 +90,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
*/
public BlockContainerLayoutManager(BlockContainer node) {
super(node);
setGeneratesBlockArea(true);
}

/** {@inheritDoc} */
@@ -128,6 +123,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
.spaceAfter.getSpace().getOptimum(this).getLength().getValue(this);
}

@Override
protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
return getBlockContainerFO().getCommonBorderPaddingBackground();
}

private void resetSpaces() {
this.discardBorderBefore = false;
this.discardBorderAfter = false;
@@ -867,6 +867,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
transferForeignAttributes(viewportBlockArea);

TraitSetter.setProducerID(viewportBlockArea, getBlockContainerFO().getId());
TraitSetter.setLayer(viewportBlockArea, getBlockContainerFO().getLayer());
TraitSetter.addBorders(viewportBlockArea,
getBlockContainerFO().getCommonBorderPaddingBackground(),
discardBorderBefore, discardBorderAfter, false, false, this);
@@ -993,51 +994,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
return true;
}

/** {@inheritDoc} */
public void notifySpace(RelSide side, MinOptMax effectiveLength) {
if (RelSide.BEFORE == side) {
if (log.isDebugEnabled()) {
log.debug(this + ": Space " + side + ", "
+ this.effSpaceBefore + "-> " + effectiveLength);
}
this.effSpaceBefore = effectiveLength;
} else {
if (log.isDebugEnabled()) {
log.debug(this + ": Space " + side + ", "
+ this.effSpaceAfter + "-> " + effectiveLength);
}
this.effSpaceAfter = effectiveLength;
}
}

/** {@inheritDoc} */
public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
if (effectiveLength == null) {
if (RelSide.BEFORE == side) {
this.discardBorderBefore = true;
} else {
this.discardBorderAfter = true;
}
}
if (log.isDebugEnabled()) {
log.debug(this + ": Border " + side + " -> " + effectiveLength);
}
}

/** {@inheritDoc} */
public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
if (effectiveLength == null) {
if (RelSide.BEFORE == side) {
this.discardPaddingBefore = true;
} else {
this.discardPaddingAfter = true;
}
}
if (log.isDebugEnabled()) {
log.debug(this + ": Padding " + side + " -> " + effectiveLength);
}
}

/** {@inheritDoc} */
public boolean handleOverflow(int milliPoints) {
if (milliPoints > this.horizontalOverflow) {

+ 10
- 55
src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java View File

@@ -32,6 +32,7 @@ import org.apache.fop.area.Block;
import org.apache.fop.area.LineArea;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
@@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal;
/**
* LayoutManager for a block FO.
*/
public class BlockLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener,
BreakOpportunity {
public class BlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
implements BreakOpportunity {

/** logging instance */
private static Log log = LogFactory.getLog(BlockLayoutManager.class);
@@ -60,13 +61,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
private int follow = 2000;
//private int middleShift = 0;

private boolean discardBorderBefore;
private boolean discardBorderAfter;
private boolean discardPaddingBefore;
private boolean discardPaddingAfter;
private MinOptMax effSpaceBefore;
private MinOptMax effSpaceAfter;

/**
* Creates a new BlockLayoutManager.
* @param inBlock the block FO object to create the layout manager for.
@@ -100,6 +94,11 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
.getOptimum(this).getLength().getValue(this);
}

@Override
protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
return getBlockFO().getCommonBorderPaddingBackground();
}

/** {@inheritDoc} */
@Override
public List getNextKnuthElements(LayoutContext context, int alignment) {
@@ -360,7 +359,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co

curBlockArea.setIPD(super.getContentAreaIPD());

curBlockArea.setBidiLevel(getBlockFO().getBidiLevel());
curBlockArea.setBidiLevel(getBlockFO().getBidiLevelRecursive());

TraitSetter.addBreaks(curBlockArea,
getBlockFO().getBreakBefore(), getBlockFO().getBreakAfter());
@@ -381,6 +380,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
getBlockFO().getCommonBorderPaddingBackground(),
startIndent, endIndent,
this);
TraitSetter.setLayer(curBlockArea, getBlockFO().getLayer());

curBlockArea.setLocale(getBlockFO().getCommonHyphenation().getLocale());
curBlockArea.setLocation(FONode.getLocatorString(getBlockFO().getLocator()));
@@ -456,51 +456,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
return true;
}

/** {@inheritDoc} */
public void notifySpace(RelSide side, MinOptMax effectiveLength) {
if (RelSide.BEFORE == side) {
if (log.isDebugEnabled()) {
log.debug(this + ": Space " + side + ", "
+ this.effSpaceBefore + "-> " + effectiveLength);
}
this.effSpaceBefore = effectiveLength;
} else {
if (log.isDebugEnabled()) {
log.debug(this + ": Space " + side + ", "
+ this.effSpaceAfter + "-> " + effectiveLength);
}
this.effSpaceAfter = effectiveLength;
}
}

/** {@inheritDoc} */
public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
if (effectiveLength == null) {
if (RelSide.BEFORE == side) {
this.discardBorderBefore = true;
} else {
this.discardBorderAfter = true;
}
}
if (log.isDebugEnabled()) {
log.debug(this + ": Border " + side + " -> " + effectiveLength);
}
}

/** {@inheritDoc} */
public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
if (effectiveLength == null) {
if (RelSide.BEFORE == side) {
this.discardPaddingBefore = true;
} else {
this.discardPaddingAfter = true;
}
}
if (log.isDebugEnabled()) {
log.debug(this + ": Padding " + side + " -> " + effectiveLength);
}
}

/** {@inheritDoc} */
@Override
public boolean isRestartable() {

+ 3
- 0
src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java View File

@@ -36,6 +36,7 @@ import org.apache.fop.fo.properties.BreakPropertySet;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.SpaceProperty;
import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager;
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.util.ListUtil;
@@ -1246,6 +1247,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
public boolean handleOverflow(int milliPoints) {
if (getParent() instanceof BlockStackingLayoutManager) {
return ((BlockStackingLayoutManager) getParent()).handleOverflow(milliPoints);
} else if (getParent() instanceof InlineContainerLayoutManager) {
return ((InlineContainerLayoutManager) getParent()).handleOverflow(milliPoints);
}
return false;
}

+ 8
- 2
src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java View File

@@ -242,8 +242,14 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan
pv.setPage(pageArea);

RegionViewport rv = new RegionViewport(referenceRect);
rv.setIPD(referenceRect.width);
rv.setBPD(referenceRect.height);

if (pageSeq.getReferenceOrientation() % 180 == 0) {
rv.setIPD(referenceRect.width);
rv.setBPD(referenceRect.height);
} else {
rv.setIPD(referenceRect.height);
rv.setBPD(referenceRect.width);
}
rv.setClip(true);

BodyRegion body = new BodyRegion(Constants.FO_REGION_BODY,

+ 1
- 0
src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java View File

@@ -58,6 +58,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
*/
public FlowLayoutManager(PageSequenceLayoutManager pslm, Flow node) {
super(node);
setGeneratesBlockArea(true);
setParent(pslm);
}


+ 19
- 0
src/java/org/apache/fop/layoutmgr/LayoutManager.java View File

@@ -177,6 +177,25 @@ public interface LayoutManager extends PercentBaseContext {
*/
List getChangedKnuthElements(List oldList, int alignment);

/**
* Whether the FO handled by this layout manager has a descendant (including itself)
* that will generate a line-area.
*
* @return {@code true} if a descendant line-area will be generated, {@code false} otherwise
*/
boolean hasLineAreaDescendant();

/**
* Returns the position of the dominant-baseline of this FO's first descendant
* line-area. <p>The behavior of this method is undefined if this FO has no descendant
* line-area, and an exception may be thrown. See {@link #hasLineAreaDescendant()}</p>
*
* @return this FO's space-before plus the distance from the before-edge of its
* allocation-rectangle to the dominant-baseline of the first line-area descendant
* @see #hasLineAreaDescendant()
*/
int getBaselineOffset();

/**
* Returns the IPD of the content area
* @return the IPD of the content area

+ 5
- 7
src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java View File

@@ -73,7 +73,7 @@ import org.apache.fop.layoutmgr.inline.CharacterLayoutManager;
import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager;
import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager;
import org.apache.fop.layoutmgr.inline.ICLayoutManager;
import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager;
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM;
import org.apache.fop.layoutmgr.inline.LeaderLayoutManager;
@@ -257,9 +257,9 @@ public class LayoutManagerMapping implements LayoutManagerMaker {
/** a layout manager maker */
public static class InlineLayoutManagerMaker extends Maker {
/** {@inheritDoc} */
public void make(FONode node, List lms) {
lms.add(new InlineLayoutManager((InlineLevel) node));
}
public void make(FONode node, List lms) {
lms.add(new InlineLayoutManager((InlineLevel) node));
}
}

/** a layout manager maker */
@@ -274,9 +274,7 @@ public class LayoutManagerMapping implements LayoutManagerMaker {
public static class InlineContainerLayoutManagerMaker extends Maker {
/** {@inheritDoc} */
public void make(FONode node, List lms) {
ArrayList childList = new ArrayList();
super.make(node, childList);
lms.add(new ICLayoutManager((InlineContainer) node, childList));
lms.add(new InlineContainerLayoutManager((InlineContainer) node));
}
}


+ 46
- 32
src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java View File

@@ -140,7 +140,10 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
*/
protected class KnuthPageNode extends KnuthNode {

/** Additional length due to footnotes. */
/** Additional length due to already inserted footnotes. */
public int insertedFootnotes;

/** Total length of the footnotes. */
public int totalFootnotes;

/** Index of the last inserted footnote. */
@@ -152,7 +155,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
public KnuthPageNode(int position,
int line, int fitness,
int totalWidth, int totalStretch, int totalShrink,
int totalFootnotes, int footnoteListIndex, int footnoteElementIndex,
int insertedFootnotes, int totalFootnotes,
int footnoteListIndex, int footnoteElementIndex,
double adjustRatio, int availableShrink, int availableStretch,
int difference, double totalDemerits, KnuthNode previous) {
super(position, line, fitness,
@@ -160,6 +164,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
adjustRatio, availableShrink, availableStretch,
difference, totalDemerits, previous);
this.totalFootnotes = totalFootnotes;
this.insertedFootnotes = insertedFootnotes;
this.footnoteListIndex = footnoteListIndex;
this.footnoteElementIndex = footnoteElementIndex;
}
@@ -172,7 +177,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
*/
protected class BestPageRecords extends BestRecords {

private int[] bestFootnotesLength = new int[4];
private int[] bestInsertedFootnotesLength = new int[4];
private int[] bestTotalFootnotesLength = new int[4];
private int[] bestFootnoteListIndex = new int[4];
private int[] bestFootnoteElementIndex = new int[4];

@@ -182,13 +188,18 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
super.addRecord(demerits, node, adjust,
availableShrink, availableStretch,
difference, fitness);
bestFootnotesLength[fitness] = insertedFootnotesLength;
bestInsertedFootnotesLength[fitness] = insertedFootnotesLength;
bestTotalFootnotesLength[fitness] = totalFootnotesLength;
bestFootnoteListIndex[fitness] = footnoteListIndex;
bestFootnoteElementIndex[fitness] = footnoteElementIndex;
}

public int getFootnotesLength(int fitness) {
return bestFootnotesLength[fitness];
public int getInsertedFootnotesLength(int fitness) {
return bestInsertedFootnotesLength[fitness];
}

public int getTotalFootnotesLength(int fitness) {
return bestTotalFootnotesLength[fitness];
}

public int getFootnoteListIndex(int fitness) {
@@ -287,7 +298,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
int difference, double totalDemerits, KnuthNode previous) {
return new KnuthPageNode(position, line, fitness,
totalWidth, totalStretch, totalShrink,
insertedFootnotesLength, footnoteListIndex, footnoteElementIndex,
insertedFootnotesLength, totalFootnotesLength,
footnoteListIndex, footnoteElementIndex,
adjustRatio, availableShrink, availableStretch,
difference, totalDemerits, previous);
}
@@ -298,7 +310,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
int totalWidth, int totalStretch, int totalShrink) {
return new KnuthPageNode(position, line, fitness,
totalWidth, totalStretch, totalShrink,
((BestPageRecords) best).getFootnotesLength(fitness),
((BestPageRecords) best).getInsertedFootnotesLength(fitness),
((BestPageRecords) best).getTotalFootnotesLength(fitness),
((BestPageRecords) best).getFootnoteListIndex(fitness),
((BestPageRecords) best).getFootnoteElementIndex(fitness),
best.getAdjust(fitness), best.getAvailableShrink(fitness),
@@ -405,6 +418,12 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
resetFootnotes(((KnuthBlockBox) resetElement).getElementLists());
}
}
assert restartingNode instanceof KnuthPageNode;
KnuthPageNode restartingPageNode = (KnuthPageNode) restartingNode;
footnoteElementIndex = restartingPageNode.footnoteElementIndex;
footnoteListIndex = restartingPageNode.footnoteListIndex;
totalFootnotesLength = restartingPageNode.totalFootnotes;
insertedFootnotesLength = restartingPageNode.insertedFootnotes;
}
return returnValue;
}
@@ -413,13 +432,6 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
for (int i = 0; i < elementLists.size(); i++) {
ListUtil.removeLast(footnotesList);
ListUtil.removeLast(lengthList);

// update totalFootnotesLength
if (!lengthList.isEmpty()) {
totalFootnotesLength = ListUtil.getLast(lengthList);
} else {
totalFootnotesLength = 0;
}
}
// update footnotesPending;
if (footnotesList.size() == 0) {
@@ -502,7 +514,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
}
if (footnotesPending) {
// compute the total length of the footnotes not yet inserted
int allFootnotes = totalFootnotesLength - pageNode.totalFootnotes;
int allFootnotes = totalFootnotesLength - pageNode.insertedFootnotes;
if (allFootnotes > 0) {
// this page contains some footnote citations
// add the footnote separator width
@@ -511,7 +523,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
// there is enough space to insert all footnotes:
// add the whole allFootnotes length
actualWidth += allFootnotes;
insertedFootnotesLength = pageNode.totalFootnotes + allFootnotes;
insertedFootnotesLength = pageNode.insertedFootnotes + allFootnotes;
footnoteListIndex = footnotesList.size() - 1;
footnoteElementIndex
= getFootnoteList(footnoteListIndex).size() - 1;
@@ -528,7 +540,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
// this is the first feasible break; in this case it is allowed
// to break and defer, if necessary, old and new footnotes
actualWidth += footnoteSplit;
insertedFootnotesLength = pageNode.totalFootnotes + footnoteSplit;
insertedFootnotesLength = pageNode.insertedFootnotes + footnoteSplit;
// footnoteListIndex has been set in getFootnoteSplit()
// footnoteElementIndex has been set in getFootnoteSplit()
} else {
@@ -538,7 +550,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
// that cannot be broken:
// add the whole allFootnotes length, so this breakpoint will be discarded
actualWidth += allFootnotes;
insertedFootnotesLength = pageNode.totalFootnotes + allFootnotes;
insertedFootnotesLength = pageNode.insertedFootnotes + allFootnotes;
footnoteListIndex = footnotesList.size() - 1;
footnoteElementIndex
= getFootnoteList(footnoteListIndex).size() - 1;
@@ -569,7 +581,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
private boolean canDeferOldFootnotes(KnuthPageNode node, int contentElementIndex) {
return (noBreakBetween(node.position, contentElementIndex)
&& deferredFootnotes(node.footnoteListIndex,
node.footnoteElementIndex, node.totalFootnotes));
node.footnoteElementIndex, node.insertedFootnotes));
}

/**
@@ -649,7 +661,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
boolean canDeferOldFootnotes) {
return getFootnoteSplit(activeNode.footnoteListIndex,
activeNode.footnoteElementIndex,
activeNode.totalFootnotes,
activeNode.insertedFootnotes,
availableLength, canDeferOldFootnotes);
}

@@ -714,10 +726,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
int prevIndex = -1;
int index = -1;

while (!(somethingAdded && splitLength > availableLength)) {
if (!somethingAdded) {
somethingAdded = true;
} else {
while (splitLength <= availableLength) {
if (somethingAdded) {
prevSplitLength = splitLength;
prevIndex = index;
}
@@ -733,6 +743,10 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
// element is a box
splitLength += element.getWidth();
boxPreceding = true;
if (splitLength > prevSplitLength) {
// and it is non-empty
somethingAdded = true;
}
} else if (element.isGlue()) {
// element is a glue
if (boxPreceding) {
@@ -749,6 +763,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
index = noteListIterator.previousIndex();
break;
}
boxPreceding = false;
}
}
}
@@ -758,7 +773,6 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
// page here
// if prevSplitLength is > 0 we can insert some footnote content in this page
// and insert the remaining in the following one
//TODO: check this conditional, as the first one is always false...?
if (!somethingAdded) {
// there was not enough space to add a piece of the first new footnote
// this is not a good break
@@ -781,7 +795,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
if (difference > 0) {
int maxAdjustment = totalStretch - activeNode.totalStretch;
// add the footnote separator stretch if some footnote content will be added
if (((KnuthPageNode) activeNode).totalFootnotes < totalFootnotesLength) {
if (((KnuthPageNode) activeNode).insertedFootnotes < totalFootnotesLength) {
maxAdjustment += footnoteSeparatorLength.getStretch();
}
if (maxAdjustment > 0) {
@@ -792,7 +806,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
} else if (difference < 0) {
int maxAdjustment = totalShrink - activeNode.totalShrink;
// add the footnote separator shrink if some footnote content will be added
if (((KnuthPageNode) activeNode).totalFootnotes < totalFootnotesLength) {
if (((KnuthPageNode) activeNode).insertedFootnotes < totalFootnotesLength) {
maxAdjustment += footnoteSeparatorLength.getShrink();
}
if (maxAdjustment > 0) {
@@ -866,7 +880,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
for (KnuthPageNode node = (KnuthPageNode) getNode(i);
node != null;
node = (KnuthPageNode) node.next) {
if (node.totalFootnotes < totalFootnotesLength) {
if (node.insertedFootnotes < totalFootnotesLength) {
// layout remaining footnote bodies
createFootnotePages(node);
}
@@ -876,7 +890,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {

private void createFootnotePages(KnuthPageNode lastNode) {

insertedFootnotesLength = lastNode.totalFootnotes;
insertedFootnotesLength = lastNode.insertedFootnotes;
footnoteListIndex = lastNode.footnoteListIndex;
footnoteElementIndex = lastNode.footnoteElementIndex;
int availableBPD = getLineWidth(lastNode.line);
@@ -902,7 +916,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
// cannot add any content: create a new node and start again
KnuthPageNode node = (KnuthPageNode)
createNode(lastNode.position, prevNode.line + 1, 1,
insertedFootnotesLength - prevNode.totalFootnotes,
insertedFootnotesLength - prevNode.insertedFootnotes,
0, 0,
0, 0, 0,
0, 0, prevNode);
@@ -916,7 +930,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
// create the last node
KnuthPageNode node = (KnuthPageNode)
createNode(lastNode.position, prevNode.line + 1, 1,
totalFootnotesLength - prevNode.totalFootnotes, 0, 0,
totalFootnotesLength - prevNode.insertedFootnotes, 0, 0,
0, 0, 0,
0, 0, prevNode);
addNode(node.line, node);

+ 112
- 0
src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java View File

@@ -0,0 +1,112 @@
/*
* 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.layoutmgr;

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

import org.apache.fop.fo.FObj;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.traits.MinOptMax;

/**
* A block-stacking layout manager for an FO that supports spaces, border and padding.
*/
public abstract class SpacedBorderedPaddedBlockLayoutManager extends BlockStackingLayoutManager
implements ConditionalElementListener {

private static final Log LOG = LogFactory.getLog(BlockLayoutManager.class);

protected MinOptMax effSpaceBefore;

protected MinOptMax effSpaceAfter;

protected boolean discardBorderBefore;
protected boolean discardBorderAfter;
protected boolean discardPaddingBefore;
protected boolean discardPaddingAfter;

public SpacedBorderedPaddedBlockLayoutManager(FObj node) {
super(node);
}

public void notifySpace(RelSide side, MinOptMax effectiveLength) {
if (RelSide.BEFORE == side) {
if (LOG.isDebugEnabled()) {
LOG.debug(this + ": Space " + side + ", "
+ this.effSpaceBefore + "-> " + effectiveLength);
}
this.effSpaceBefore = effectiveLength;
} else {
if (LOG.isDebugEnabled()) {
LOG.debug(this + ": Space " + side + ", "
+ this.effSpaceAfter + "-> " + effectiveLength);
}
this.effSpaceAfter = effectiveLength;
}
}

public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
if (effectiveLength == null) {
if (RelSide.BEFORE == side) {
this.discardBorderBefore = true;
} else {
this.discardBorderAfter = true;
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(this + ": Border " + side + " -> " + effectiveLength);
}
}

public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
if (effectiveLength == null) {
if (RelSide.BEFORE == side) {
this.discardPaddingBefore = true;
} else {
this.discardPaddingAfter = true;
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(this + ": Padding " + side + " -> " + effectiveLength);
}
}

@Override
public int getBaselineOffset() {
int baselineOffset = super.getBaselineOffset();
if (effSpaceBefore != null) {
baselineOffset += effSpaceBefore.getOpt();
}
if (!discardBorderBefore) {
baselineOffset += getCommonBorderPaddingBackground().getBorderBeforeWidth(false);
}
if (!discardPaddingBefore) {
baselineOffset += getCommonBorderPaddingBackground().getPaddingBefore(false, this);
}
return baselineOffset;
}

/**
* Returns the {@link CommonBorderPaddingBackground} instance from the FO handled by this layout manager.
*/
protected abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground();

}

+ 0
- 0
src/java/org/apache/fop/layoutmgr/TraitSetter.java View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save