Adrian Cumiskey 15 years ago
parent
commit
4d4e2cd48e
100 changed files with 11357 additions and 265 deletions
  1. 1
    0
      build.xml
  2. 312
    0
      conf/fop.xconf
  3. 1
    1
      lib/README.txt
  4. 5
    0
      src/documentation/content/xdocs/team.xml
  5. 30
    0
      src/documentation/content/xdocs/trunk/configuration.xml
  6. 59
    5
      src/documentation/content/xdocs/trunk/output.xml
  7. 5
    0
      src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler
  8. 194
    0
      src/java/org/apache/fop/afp/AFPBorderPainter.java
  9. 17
    1
      src/java/org/apache/fop/afp/AFPConstants.java
  10. 272
    0
      src/java/org/apache/fop/afp/AFPDataObjectFactory.java
  11. 247
    0
      src/java/org/apache/fop/afp/AFPDataObjectInfo.java
  12. 21
    1
      src/java/org/apache/fop/afp/AFPEventProducer.java
  13. 6
    0
      src/java/org/apache/fop/afp/AFPEventProducer.xml
  14. 698
    0
      src/java/org/apache/fop/afp/AFPGraphics2D.java
  15. 109
    0
      src/java/org/apache/fop/afp/AFPGraphicsObjectInfo.java
  16. 115
    0
      src/java/org/apache/fop/afp/AFPImageObjectInfo.java
  17. 192
    0
      src/java/org/apache/fop/afp/AFPLineDataInfo.java
  18. 172
    0
      src/java/org/apache/fop/afp/AFPObjectAreaInfo.java
  19. 495
    0
      src/java/org/apache/fop/afp/AFPPaintingState.java
  20. 84
    0
      src/java/org/apache/fop/afp/AFPRectanglePainter.java
  21. 141
    0
      src/java/org/apache/fop/afp/AFPResourceInfo.java
  22. 201
    0
      src/java/org/apache/fop/afp/AFPResourceLevel.java
  23. 179
    0
      src/java/org/apache/fop/afp/AFPResourceManager.java
  24. 215
    0
      src/java/org/apache/fop/afp/AFPStreamer.java
  25. 232
    0
      src/java/org/apache/fop/afp/AFPTextDataInfo.java
  26. 121
    0
      src/java/org/apache/fop/afp/AFPUnitConverter.java
  27. 53
    0
      src/java/org/apache/fop/afp/AbstractAFPPainter.java
  28. 121
    0
      src/java/org/apache/fop/afp/BorderPaintingInfo.java
  29. 40
    0
      src/java/org/apache/fop/afp/Completable.java
  30. 602
    0
      src/java/org/apache/fop/afp/DataStream.java
  31. 635
    0
      src/java/org/apache/fop/afp/Factory.java
  32. 27
    0
      src/java/org/apache/fop/afp/PaintingInfo.java
  33. 84
    0
      src/java/org/apache/fop/afp/RectanglePaintingInfo.java
  34. 40
    0
      src/java/org/apache/fop/afp/Startable.java
  35. 38
    0
      src/java/org/apache/fop/afp/Streamable.java
  36. 33
    0
      src/java/org/apache/fop/afp/StructuredData.java
  37. 157
    0
      src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java
  38. 6
    2
      src/java/org/apache/fop/afp/fonts/AFPFont.java
  39. 25
    19
      src/java/org/apache/fop/afp/fonts/AFPFontAttributes.java
  40. 92
    0
      src/java/org/apache/fop/afp/fonts/AFPFontCollection.java
  41. 11
    7
      src/java/org/apache/fop/afp/fonts/AFPFontInfo.java
  42. 4
    4
      src/java/org/apache/fop/afp/fonts/AFPFontReader.java
  43. 64
    0
      src/java/org/apache/fop/afp/fonts/AFPPageFonts.java
  44. 5
    5
      src/java/org/apache/fop/afp/fonts/CharacterSet.java
  45. 1
    1
      src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
  46. 4
    2
      src/java/org/apache/fop/afp/fonts/FontRuntimeException.java
  47. 1
    1
      src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
  48. 2
    1
      src/java/org/apache/fop/afp/fonts/OutlineFont.java
  49. 10
    10
      src/java/org/apache/fop/afp/fonts/RasterFont.java
  50. 23
    0
      src/java/org/apache/fop/afp/fonts/package.html
  51. 149
    0
      src/java/org/apache/fop/afp/goca/AbstractGraphicsCoord.java
  52. 60
    0
      src/java/org/apache/fop/afp/goca/AbstractGraphicsDrawingOrder.java
  53. 158
    0
      src/java/org/apache/fop/afp/goca/AbstractGraphicsDrawingOrderContainer.java
  54. 69
    0
      src/java/org/apache/fop/afp/goca/GraphicsAreaBegin.java
  55. 53
    0
      src/java/org/apache/fop/afp/goca/GraphicsAreaEnd.java
  56. 63
    0
      src/java/org/apache/fop/afp/goca/GraphicsBox.java
  57. 112
    0
      src/java/org/apache/fop/afp/goca/GraphicsChainedSegment.java
  58. 114
    0
      src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
  59. 126
    0
      src/java/org/apache/fop/afp/goca/GraphicsData.java
  60. 46
    0
      src/java/org/apache/fop/afp/goca/GraphicsFillet.java
  61. 85
    0
      src/java/org/apache/fop/afp/goca/GraphicsFullArc.java
  62. 120
    0
      src/java/org/apache/fop/afp/goca/GraphicsImage.java
  63. 56
    0
      src/java/org/apache/fop/afp/goca/GraphicsLine.java
  64. 51
    0
      src/java/org/apache/fop/afp/goca/GraphicsSetArcParameters.java
  65. 66
    0
      src/java/org/apache/fop/afp/goca/GraphicsSetCharacterSet.java
  66. 40
    0
      src/java/org/apache/fop/afp/goca/GraphicsSetCurrentPosition.java
  67. 97
    0
      src/java/org/apache/fop/afp/goca/GraphicsSetLineType.java
  68. 65
    0
      src/java/org/apache/fop/afp/goca/GraphicsSetLineWidth.java
  69. 69
    0
      src/java/org/apache/fop/afp/goca/GraphicsSetMix.java
  70. 117
    0
      src/java/org/apache/fop/afp/goca/GraphicsSetPatternSymbol.java
  71. 104
    0
      src/java/org/apache/fop/afp/goca/GraphicsSetProcessColor.java
  72. 23
    0
      src/java/org/apache/fop/afp/goca/package.html
  73. 24
    41
      src/java/org/apache/fop/afp/ioca/ImageCellPosition.java
  74. 267
    0
      src/java/org/apache/fop/afp/ioca/ImageContent.java
  75. 10
    21
      src/java/org/apache/fop/afp/ioca/ImageInputDescriptor.java
  76. 8
    17
      src/java/org/apache/fop/afp/ioca/ImageOutputControl.java
  77. 14
    27
      src/java/org/apache/fop/afp/ioca/ImageRasterData.java
  78. 1
    1
      src/java/org/apache/fop/afp/ioca/ImageRasterPattern.java
  79. 161
    0
      src/java/org/apache/fop/afp/ioca/ImageSegment.java
  80. 14
    15
      src/java/org/apache/fop/afp/ioca/ImageSizeParameter.java
  81. 23
    0
      src/java/org/apache/fop/afp/ioca/package.html
  82. 321
    0
      src/java/org/apache/fop/afp/modca/AbstractAFPObject.java
  83. 140
    0
      src/java/org/apache/fop/afp/modca/AbstractDataObject.java
  84. 44
    9
      src/java/org/apache/fop/afp/modca/AbstractDescriptor.java
  85. 101
    0
      src/java/org/apache/fop/afp/modca/AbstractEnvironmentGroup.java
  86. 122
    0
      src/java/org/apache/fop/afp/modca/AbstractNamedAFPObject.java
  87. 350
    0
      src/java/org/apache/fop/afp/modca/AbstractPageObject.java
  88. 99
    0
      src/java/org/apache/fop/afp/modca/AbstractResourceEnvironmentGroupContainer.java
  89. 168
    0
      src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java
  90. 69
    0
      src/java/org/apache/fop/afp/modca/AbstractStructuredObject.java
  91. 181
    0
      src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java
  92. 221
    0
      src/java/org/apache/fop/afp/modca/ActiveEnvironmentGroup.java
  93. 84
    0
      src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java
  94. 96
    0
      src/java/org/apache/fop/afp/modca/Document.java
  95. 152
    0
      src/java/org/apache/fop/afp/modca/GraphicsDataDescriptor.java
  96. 385
    0
      src/java/org/apache/fop/afp/modca/GraphicsObject.java
  97. 24
    74
      src/java/org/apache/fop/afp/modca/IMImageObject.java
  98. 78
    0
      src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java
  99. 155
    0
      src/java/org/apache/fop/afp/modca/ImageObject.java
  100. 0
    0
      src/java/org/apache/fop/afp/modca/IncludeObject.java

+ 1
- 0
build.xml View File

@@ -612,6 +612,7 @@ list of possible build targets.
<exclude name="org/apache/fop/render/pdf/PDFRenderer.class"/>
<exclude name="org/apache/fop/render/pdf/PDFXMLHandler*"/>
<include name="org/apache/fop/render/*RendererConfigurator**"/>
<include name="org/apache/fop/util/AbstractPaintingState**"/>
<include name="org/apache/fop/pdf/**"/>
</patternset>
<!-- PS transcoder -->

+ 312
- 0
conf/fop.xconf View File

@@ -87,6 +87,318 @@ the location of this file.

</renderer>

<renderer mime="application/x-afp">
<!--
The bit depth and type of images produced
(this is the default setting)
-->
<images mode="b+w" bits-per-pixel="8"/>
<renderer-resolution>240</renderer-resolution>
<resource-group-file>resources.afp</resource-group-file>

<fonts>
<!--
Below is an example using raster font configuration using FOP builtin base-14 font metrics.
for Times Roman, Helvetica and Courier.

Depending on AFP raster and outline font availability on your installation you will
most likely need to modify the configuration provided below.

See http://xmlgraphics.apache.org/fop/trunk/output.html#afp-configuration
for details of FOP configuration for AFP
-->

<!-- Times Roman -->
<font>
<afp-font name="Times Roman" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0N20060" base14-font="TimesRoman"/>
<afp-raster-font size="7" characterset="C0N20070" base14-font="TimesRoman"/>
<afp-raster-font size="8" characterset="C0N20080" base14-font="TimesRoman"/>
<afp-raster-font size="9" characterset="C0N20090" base14-font="TimesRoman"/>
<afp-raster-font size="10" characterset="C0N20000" base14-font="TimesRoman"/>
<afp-raster-font size="11" characterset="C0N200A0" base14-font="TimesRoman"/>
<afp-raster-font size="12" characterset="C0N200B0" base14-font="TimesRoman"/>
<afp-raster-font size="14" characterset="C0N200D0" base14-font="TimesRoman"/>
<afp-raster-font size="16" characterset="C0N200F0" base14-font="TimesRoman"/>
<afp-raster-font size="18" characterset="C0N200H0" base14-font="TimesRoman"/>
<afp-raster-font size="20" characterset="C0N200J0" base14-font="TimesRoman"/>
<afp-raster-font size="24" characterset="C0N200N0" base14-font="TimesRoman"/>
<afp-raster-font size="30" characterset="C0N200T0" base14-font="TimesRoman"/>
<afp-raster-font size="36" characterset="C0N200Z0" base14-font="TimesRoman"/>
</afp-font>
<font-triplet name="Times" style="normal" weight="normal"/>
<font-triplet name="TimesRoman" style="normal" weight="normal"/>
<font-triplet name="Times Roman" style="normal" weight="normal"/>
<font-triplet name="Times-Roman" style="normal" weight="normal"/>
<font-triplet name="Times New Roman" style="normal" weight="normal"/>
<font-triplet name="TimesNewRoman" style="normal" weight="normal"/>
<font-triplet name="serif" style="normal" weight="normal"/>
</font>
<!-- Times Roman Italic -->
<font>
<afp-font name="Times Roman Italic" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0N30060" base14-font="TimesItalic"/>
<afp-raster-font size="7" characterset="C0N30070" base14-font="TimesItalic"/>
<afp-raster-font size="8" characterset="C0N30080" base14-font="TimesItalic"/>
<afp-raster-font size="9" characterset="C0N30090" base14-font="TimesItalic"/>
<afp-raster-font size="10" characterset="C0N30000" base14-font="TimesItalic"/>
<afp-raster-font size="11" characterset="C0N300A0" base14-font="TimesItalic"/>
<afp-raster-font size="12" characterset="C0N300B0" base14-font="TimesItalic"/>
<afp-raster-font size="14" characterset="C0N300D0" base14-font="TimesItalic"/>
<afp-raster-font size="16" characterset="C0N300F0" base14-font="TimesItalic"/>
<afp-raster-font size="18" characterset="C0N300H0" base14-font="TimesItalic"/>
<afp-raster-font size="20" characterset="C0N300J0" base14-font="TimesItalic"/>
<afp-raster-font size="24" characterset="C0N300N0" base14-font="TimesItalic"/>
<afp-raster-font size="30" characterset="C0N300T0" base14-font="TimesItalic"/>
<afp-raster-font size="36" characterset="C0N300Z0" base14-font="TimesItalic"/>
</afp-font>
<font-triplet name="Times" style="italic" weight="normal"/>
<font-triplet name="TimesRoman" style="italic" weight="normal"/>
<font-triplet name="Times Roman" style="italic" weight="normal"/>
<font-triplet name="Times-Roman" style="italic" weight="normal"/>
<font-triplet name="Times New Roman" style="italic" weight="normal"/>
<font-triplet name="TimesNewRoman" style="italic" weight="normal"/>
<font-triplet name="serif" style="italic" weight="normal"/>
</font>
<!-- Times Roman Bold -->
<font>
<afp-font name="Times Roman Bold" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0N40060" base14-font="TimesBold"/>
<afp-raster-font size="7" characterset="C0N40070" base14-font="TimesBold"/>
<afp-raster-font size="8" characterset="C0N40080" base14-font="TimesBold"/>
<afp-raster-font size="9" characterset="C0N40090" base14-font="TimesBold"/>
<afp-raster-font size="10" characterset="C0N40000" base14-font="TimesBold"/>
<afp-raster-font size="11" characterset="C0N400A0" base14-font="TimesBold"/>
<afp-raster-font size="12" characterset="C0N400B0" base14-font="TimesBold"/>
<afp-raster-font size="14" characterset="C0N400D0" base14-font="TimesBold"/>
<afp-raster-font size="16" characterset="C0N400F0" base14-font="TimesBold"/>
<afp-raster-font size="18" characterset="C0N400H0" base14-font="TimesBold"/>
<afp-raster-font size="20" characterset="C0N400J0" base14-font="TimesBold"/>
<afp-raster-font size="24" characterset="C0N400N0" base14-font="TimesBold"/>
<afp-raster-font size="30" characterset="C0N400T0" base14-font="TimesBold"/>
<afp-raster-font size="36" characterset="C0N400Z0" base14-font="TimesBold"/>
</afp-font>
<font-triplet name="Times" style="normal" weight="bold"/>
<font-triplet name="TimesRoman" style="normal" weight="bold"/>
<font-triplet name="Times Roman" style="normal" weight="bold"/>
<font-triplet name="Times-Roman" style="normal" weight="bold"/>
<font-triplet name="Times New Roman" style="normal" weight="bold"/>
<font-triplet name="TimesNewRoman" style="normal" weight="bold"/>
<font-triplet name="serif" style="normal" weight="bold"/>
</font>

<!-- Times Roman Italic Bold -->
<font>
<afp-font name="Times Roman Italic Bold" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0N50060" base14-font="TimesBoldItalic"/>
<afp-raster-font size="7" characterset="C0N50070" base14-font="TimesBoldItalic"/>
<afp-raster-font size="8" characterset="C0N50080" base14-font="TimesBoldItalic"/>
<afp-raster-font size="9" characterset="C0N50090" base14-font="TimesBoldItalic"/>
<afp-raster-font size="10" characterset="C0N50000" base14-font="TimesBoldItalic"/>
<afp-raster-font size="11" characterset="C0N500A0" base14-font="TimesBoldItalic"/>
<afp-raster-font size="12" characterset="C0N500B0" base14-font="TimesBoldItalic"/>
<afp-raster-font size="14" characterset="C0N500D0" base14-font="TimesBoldItalic"/>
<afp-raster-font size="16" characterset="C0N500F0" base14-font="TimesBoldItalic"/>
<afp-raster-font size="18" characterset="C0N500H0" base14-font="TimesBoldItalic"/>
<afp-raster-font size="20" characterset="C0N500J0" base14-font="TimesBoldItalic"/>
<afp-raster-font size="24" characterset="C0N500N0" base14-font="TimesBoldItalic"/>
<afp-raster-font size="30" characterset="C0N500T0" base14-font="TimesBoldItalic"/>
<afp-raster-font size="36" characterset="C0N500Z0" base14-font="TimesBoldItalic"/>
</afp-font>
<font-triplet name="Times" style="italic" weight="bold"/>
<font-triplet name="TimesRoman" style="italic" weight="bold"/>
<font-triplet name="Times Roman" style="italic" weight="bold"/>
<font-triplet name="Times-Roman" style="italic" weight="bold"/>
<font-triplet name="Times New Roman" style="italic" weight="bold"/>
<font-triplet name="TimesNewRoman" style="italic" weight="bold"/>
<font-triplet name="serif" style="italic" weight="bold"/>
</font>

<!-- Helvetica -->
<font>
<afp-font name="Helvetica" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0H20060" base14-font="Helvetica"/>
<afp-raster-font size="7" characterset="C0H20070" base14-font="Helvetica"/>
<afp-raster-font size="8" characterset="C0H20080" base14-font="Helvetica"/>
<afp-raster-font size="9" characterset="C0H20090" base14-font="Helvetica"/>
<afp-raster-font size="10" characterset="C0H20000" base14-font="Helvetica"/>
<afp-raster-font size="11" characterset="C0H200A0" base14-font="Helvetica"/>
<afp-raster-font size="12" characterset="C0H200B0" base14-font="Helvetica"/>
<afp-raster-font size="14" characterset="C0H200D0" base14-font="Helvetica"/>
<afp-raster-font size="16" characterset="C0H200F0" base14-font="Helvetica"/>
<afp-raster-font size="18" characterset="C0H200H0" base14-font="Helvetica"/>
<afp-raster-font size="20" characterset="C0H200J0" base14-font="Helvetica"/>
<afp-raster-font size="24" characterset="C0H200N0" base14-font="Helvetica"/>
<afp-raster-font size="30" characterset="C0H200T0" base14-font="Helvetica"/>
<afp-raster-font size="36" characterset="C0H200Z0" base14-font="Helvetica"/>
</afp-font>
<font-triplet name="Helvetica" style="normal" weight="normal"/>
<font-triplet name="Arial" style="normal" weight="normal"/>
<font-triplet name="sans-serif" style="normal" weight="normal"/>
<font-triplet name="any" style="normal" weight="normal"/>
</font>

<!-- Helvetica Italic -->
<font>
<afp-font name="Helvetica Italic" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0H30060" base14-font="HelveticaOblique"/>
<afp-raster-font size="7" characterset="C0H30070" base14-font="HelveticaOblique"/>
<afp-raster-font size="8" characterset="C0H30080" base14-font="HelveticaOblique"/>
<afp-raster-font size="9" characterset="C0H30090" base14-font="HelveticaOblique"/>
<afp-raster-font size="10" characterset="C0H30000" base14-font="HelveticaOblique"/>
<afp-raster-font size="11" characterset="C0H300A0" base14-font="HelveticaOblique"/>
<afp-raster-font size="12" characterset="C0H300B0" base14-font="HelveticaOblique"/>
<afp-raster-font size="14" characterset="C0H300D0" base14-font="HelveticaOblique"/>
<afp-raster-font size="16" characterset="C0H300F0" base14-font="HelveticaOblique"/>
<afp-raster-font size="18" characterset="C0H300H0" base14-font="HelveticaOblique"/>
<afp-raster-font size="20" characterset="C0H300J0" base14-font="HelveticaOblique"/>
<afp-raster-font size="24" characterset="C0H300N0" base14-font="HelveticaOblique"/>
<afp-raster-font size="30" characterset="C0H300T0" base14-font="HelveticaOblique"/>
<afp-raster-font size="36" characterset="C0H300Z0" base14-font="HelveticaOblique"/>
</afp-font>
<font-triplet name="Helvetica" style="italic" weight="normal"/>
<font-triplet name="Arial" style="italic" weight="normal"/>
<font-triplet name="sans-serif" style="italic" weight="normal"/>
</font>

<!-- Helvetica (Semi) Bold -->
<font>
<afp-font name="Helvetica (Semi) Bold" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0H40060" base14-font="HelveticaBold"/>
<afp-raster-font size="7" characterset="C0H40070" base14-font="HelveticaBold"/>
<afp-raster-font size="8" characterset="C0H40080" base14-font="HelveticaBold"/>
<afp-raster-font size="9" characterset="C0H40090" base14-font="HelveticaBold"/>
<afp-raster-font size="10" characterset="C0H40000" base14-font="HelveticaBold"/>
<afp-raster-font size="11" characterset="C0H400A0" base14-font="HelveticaBold"/>
<afp-raster-font size="12" characterset="C0H400B0" base14-font="HelveticaBold"/>
<afp-raster-font size="14" characterset="C0H400D0" base14-font="HelveticaBold"/>
<afp-raster-font size="16" characterset="C0H400F0" base14-font="HelveticaBold"/>
<afp-raster-font size="18" characterset="C0H400H0" base14-font="HelveticaBold"/>
<afp-raster-font size="20" characterset="C0H400J0" base14-font="HelveticaBold"/>
<afp-raster-font size="24" characterset="C0H400N0" base14-font="HelveticaBold"/>
<afp-raster-font size="30" characterset="C0H400T0" base14-font="HelveticaBold"/>
<afp-raster-font size="36" characterset="C0H400Z0" base14-font="HelveticaBold"/>
</afp-font>
<font-triplet name="Helvetica" style="normal" weight="bold"/>
<font-triplet name="Arial" style="normal" weight="bold"/>
<font-triplet name="sans-serif" style="normal" weight="bold"/>
</font>

<!-- Helvetica Italic (Semi) Bold -->
<font>
<afp-font name="Helvetica Italic (Semi) Bold" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0H50060" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="7" characterset="C0H50070" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="8" characterset="C0H50080" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="9" characterset="C0H50090" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="10" characterset="C0H50000" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="11" characterset="C0H500A0" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="12" characterset="C0H500B0" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="14" characterset="C0H500D0" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="16" characterset="C0H500F0" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="18" characterset="C0H500H0" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="20" characterset="C0H500J0" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="24" characterset="C0H500N0" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="30" characterset="C0H500T0" base14-font="HelveticaBoldOblique"/>
<afp-raster-font size="36" characterset="C0H500Z0" base14-font="HelveticaBoldOblique"/>
</afp-font>
<font-triplet name="Helvetica" style="italic" weight="bold"/>
<font-triplet name="Arial" style="italic" weight="bold"/>
<font-triplet name="sans-serif" style="italic" weight="bold"/>
</font>

<!-- Courier -->
<font>
<afp-font name="Courier" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0420060" base14-font="Courier"/>
<afp-raster-font size="7" characterset="C0420070" base14-font="Courier"/>
<afp-raster-font size="8" characterset="C0420080" base14-font="Courier"/>
<afp-raster-font size="9" characterset="C0420090" base14-font="Courier"/>
<afp-raster-font size="10" characterset="C0420000" base14-font="Courier"/>
<afp-raster-font size="11" characterset="C04200A0" base14-font="Courier"/>
<afp-raster-font size="12" characterset="C04200B0" base14-font="Courier"/>
<afp-raster-font size="14" characterset="C04200D0" base14-font="Courier"/>
<afp-raster-font size="16" characterset="C04200F0" base14-font="Courier"/>
<afp-raster-font size="18" characterset="C04200H0" base14-font="Courier"/>
<afp-raster-font size="20" characterset="C04200J0" base14-font="Courier"/>
<afp-raster-font size="24" characterset="C04200N0" base14-font="Courier"/>
<afp-raster-font size="30" characterset="C04200T0" base14-font="Courier"/>
<afp-raster-font size="36" characterset="C04200Z0" base14-font="Courier"/>
</afp-font>
<font-triplet name="Courier" style="normal" weight="normal"/>
<font-triplet name="monospace" style="normal" weight="normal"/>
</font>

<!-- Courier Italic -->
<font>
<afp-font name="Courier Italic" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0430060" base14-font="CourierOblique"/>
<afp-raster-font size="7" characterset="C0430070" base14-font="CourierOblique"/>
<afp-raster-font size="8" characterset="C0430080" base14-font="CourierOblique"/>
<afp-raster-font size="9" characterset="C0430090" base14-font="CourierOblique"/>
<afp-raster-font size="10" characterset="C0430000" base14-font="CourierOblique"/>
<afp-raster-font size="11" characterset="C04300A0" base14-font="CourierOblique"/>
<afp-raster-font size="12" characterset="C04300B0" base14-font="CourierOblique"/>
<afp-raster-font size="14" characterset="C04300D0" base14-font="CourierOblique"/>
<afp-raster-font size="16" characterset="C04300F0" base14-font="CourierOblique"/>
<afp-raster-font size="18" characterset="C04300H0" base14-font="CourierOblique"/>
<afp-raster-font size="20" characterset="C04300J0" base14-font="CourierOblique"/>
<afp-raster-font size="24" characterset="C04300N0" base14-font="CourierOblique"/>
<afp-raster-font size="30" characterset="C04300T0" base14-font="CourierOblique"/>
<afp-raster-font size="36" characterset="C04300Z0" base14-font="CourierOblique"/>
</afp-font>
<font-triplet name="Courier" style="italic" weight="normal"/>
<font-triplet name="monospace" style="italic" weight="normal"/>
</font>

<!-- Courier Bold -->
<font>
<afp-font name="Courier Bold" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0440060" base14-font="CourierBold"/>
<afp-raster-font size="7" characterset="C0440070" base14-font="CourierBold"/>
<afp-raster-font size="8" characterset="C0440080" base14-font="CourierBold"/>
<afp-raster-font size="9" characterset="C0440090" base14-font="CourierBold"/>
<afp-raster-font size="10" characterset="C0440000" base14-font="CourierBold"/>
<afp-raster-font size="11" characterset="C04400A0" base14-font="CourierBold"/>
<afp-raster-font size="12" characterset="C04400B0" base14-font="CourierBold"/>
<afp-raster-font size="14" characterset="C04400D0" base14-font="CourierBold"/>
<afp-raster-font size="16" characterset="C04400F0" base14-font="CourierBold"/>
<afp-raster-font size="18" characterset="C04400H0" base14-font="CourierBold"/>
<afp-raster-font size="20" characterset="C04400J0" base14-font="CourierBold"/>
<afp-raster-font size="24" characterset="C04400N0" base14-font="CourierBold"/>
<afp-raster-font size="30" characterset="C04400T0" base14-font="CourierBold"/>
<afp-raster-font size="36" characterset="C04400Z0" base14-font="CourierBold"/>
</afp-font>
<font-triplet name="Courier" style="normal" weight="bold"/>
<font-triplet name="monospace" style="normal" weight="bold"/>
</font>

<!-- Courier Italic Bold -->
<font>
<afp-font name="Courier Italic Bold" type="raster" codepage="T1V10500" encoding="Cp500">
<afp-raster-font size="6" characterset="C0450060" base14-font="CourierBoldOblique"/>
<afp-raster-font size="7" characterset="C0450070" base14-font="CourierBoldOblique"/>
<afp-raster-font size="8" characterset="C0450080" base14-font="CourierBoldOblique"/>
<afp-raster-font size="9" characterset="C0450090" base14-font="CourierBoldOblique"/>
<afp-raster-font size="10" characterset="C0450000" base14-font="CourierBoldOblique"/>
<afp-raster-font size="11" characterset="C04500A0" base14-font="CourierBoldOblique"/>
<afp-raster-font size="12" characterset="C04500B0" base14-font="CourierBoldOblique"/>
<afp-raster-font size="14" characterset="C04500D0" base14-font="CourierBoldOblique"/>
<afp-raster-font size="16" characterset="C04500F0" base14-font="CourierBoldOblique"/>
<afp-raster-font size="18" characterset="C04500H0" base14-font="CourierBoldOblique"/>
<afp-raster-font size="20" characterset="C04500J0" base14-font="CourierBoldOblique"/>
<afp-raster-font size="24" characterset="C04500N0" base14-font="CourierBoldOblique"/>
<afp-raster-font size="30" characterset="C04500T0" base14-font="CourierBoldOblique"/>
<afp-raster-font size="36" characterset="C04500Z0" base14-font="CourierBoldOblique"/>
</afp-font>
<font-triplet name="Courier" style="italic" weight="bold"/>
<font-triplet name="monospace" style="italic" weight="bold"/>
</font>
</fonts>
</renderer>

<renderer mime="application/postscript">
<!-- This option forces the PS renderer to rotate landscape pages -->
<!--auto-rotate-landscape>true</auto-rotate-landscape-->

+ 1
- 1
lib/README.txt View File

@@ -190,4 +190,4 @@ Additional development-time dependencies

(not bundled, to be added to your Apache Ant installation)
http://xmlunit.sourceforge.net/
BSD style license
BSD style license

+ 5
- 0
src/documentation/content/xdocs/team.xml View File

@@ -78,6 +78,11 @@
from the TeX/LaTeX world. See his <fork href="http://www.leverkruid.eu">home
page</fork> for some of his private projects.</li>
<li id="jp"><link href="mailto:pietsch@apache.org">J&#x00F6;rg Pietschmann</link> (JP)</li>
<li id="mb"><link href="mailto:max AT berger DOT name">Max Berger</link> (MB) is currently a
PostDoc pursuing an academic career in computer science. His main interest in FOP is to
improve the DocBook to PDF tool-chain to produce high quality output, while still
conforming to given style-guides. See his <link href="http://max.berger.name">home
page</link> for more information.</li>
</ul>
</section>
<section id="contribute-active">

+ 30
- 0
src/documentation/content/xdocs/trunk/configuration.xml View File

@@ -368,6 +368,36 @@
to "bitmap" which causes all text to be rendered as bitmaps.
</p>
</section>
<section id="afp-renderer">
<title>Special Settings for the AFP Renderer</title>
<p>
</p>
<p>
Additionally, there are certain settings that control how the renderer handles various elements.
</p>
<source><![CDATA[<renderer mime="application/x-afp">
<images mode="b+w" bits-per-pixel="8" native="true"/>
<renderer-resolution>240</renderer-resolution>
<!-- a default external resource group file -->
<resource-group-file>resources.afp</resource-group-file>
</renderer>]]></source>
<p>
The default value for the images "mode" setting is "b+w" (black and white). When the images "mode" setting is "b+w" a "bits-per-pixel" setting can be provided to aid the grayscale conversion process. With this setting all images referenced in your source document are converted to an IOCA FS45 grayscale bitmap image form.
When the setting is "color" all images are converted to an IOCA FS45 color bitmap image form. When "native" setting is "true", all images encountered (TIFF, GIF, JPEG and Encapsulated Postscript etc.) will be embedded directly in the datastream in their native form using a MO:DCA Object Container.
</p>
<p>
The default value for the "renderer-resolution" is 240 dpi.
</p>
<!--
<p>
The default value for the MO:DCA "interchange-set" is "MO:DCA-L". Other compliance settings include presentation interchange sets "MO:DCA-P IS/1" and "MO:DCA-P IS/2" (Resource Groups).
</p>
-->
<p>
By default if there is no configuration definition for "resource-group-file", external resources will be placed in a file called resources.afp.
</p>
</section>
</section>

<section>

+ 59
- 5
src/documentation/content/xdocs/trunk/output.xml View File

@@ -479,7 +479,7 @@ out = proc.getOutputStream();]]></source>
<section id="afp-configuration">
<title>Configuration</title>
<section id="afp-font-config">
<title>Fonts</title>
<title>Fonts</title>
<p>The AFP Renderer requires special configuration particularly related to fonts.
AFP Render configuration is done through the normal FOP configuration file. The MIME type
for the AFP Renderer is application/x-afp which means the AFP Renderer section in the FOP configuration file
@@ -615,16 +615,33 @@ out = proc.getOutputStream();]]></source>
<section id="afp-image-config">
<title>Images</title>
<p>By default the AFP Renderer converts all images to 8 bit grey level.
This can be overridden by the &lt;images&gt; configuration element. Example:</p>
This can be overridden by the &lt;images/&gt; configuration element. Example:</p>
<source><![CDATA[
<images mode="color" />
]]></source>
<p>This will put images as RGB images into the AFP output stream. The default setting is:</p>
<source><![CDATA[
<images mode="b+w" bits-per-pixel="8" />
<images mode="b+w" bits-per-pixel="8" native="true"/>
]]></source>
<p>Only the values "color" and "b+w" are allowed for the mode attribute.</p>
<p>The bits-per-pixel attribute is ignored if mode is "color". For "b+w" mode is must be 1, 4, or 8.</p>
<source><![CDATA[
<images native="true"/>
]]></source>
<p>When the native attribute is specified and set to "true", all image resources will be natively injected
into the datastream using an object container rather than being converted into an IOCA FS45 image.
Support for native image formats (e.g. JPEG, GIF) is not always available on printer implementations
so by default this configuration option is set to "false".</p>
</section>
<section id="afp-resource-group-file">
<title>Resource Group File</title>
<p>By default the AFP Renderer will place all data resource objects such as images within
the document of the main output datastream. An external resource group file where document resources
may be specified with the &lt;resource-group-file/&gt; configuration element. Example:</p>
<source><![CDATA[
<resource-group-file>external_resources.afp</resource-group-file>
]]></source>
<p>Only the values "color" and "b+w" are allowed for the mode attribute. The bits-per-pixel
attribute is ignored if mode is "color". For "b+w" mode is must be 1, 4, or 8.</p>
<note>Be careful when using this option not to overwrite existing resource files from previous rendering runs.</note>
</section>
</section>
<section id="afp-extensions">
@@ -709,6 +726,43 @@ out = proc.getOutputStream();]]></source>
</p>
</section>
</section>
<section id="afp-foreign-attributes">
<title>Foreign Attributes</title>
<section id="afp-foreign-attributes-resource">
<title>Resource</title>
<p>The resource foreign attributes provides the ability to name and control where data object resources
(e.g. images/scalable vector graphics) will reside in the AFP output.
The afp foreign attributes are only used in conjuntion with &lt;fo:external-graphic/&gt; and &lt;instream-foreign-object/&gt;.
Example:</p>
<source><![CDATA[
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:afp="http://xmlgraphics.apache.org/fop/extensions/afp">
...
<fo:block>
<fo:external-graphic width="2.0cm" content-width="2.0cm" height="1.8cm" content-height="1.8cm"
src="examples/fo/graphics/xml_feather.gif"
afp:resource-name="feather" afp:resource-level="external" afp:resource-group-file="resources.afp"/>
</fo:block>
<fo:block>
<fo:instream-foreign-object height="758.047pt" content-height="758.047pt" width="576.96pt" content-width="576.96pt"
afp:resource-name"circles" afp:resource-level="inline">
<svg xmlns="http://www.w3.org/2000/svg" width="12cm" height="12cm">
<g style="fill-opacity:0.7; stroke:black; stroke-width:0.1cm;">
<circle cx="6cm" cy="2cm" r="100" style="fill:red;" transform="translate(0,50)" />
<circle cx="6cm" cy="2cm" r="100" style="fill:blue;" transform="translate(70,150)" />
<circle cx="6cm" cy="2cm" r="100" style="fill:green;" transform="translate(-70,150)"/>
</g>
</svg>
</fo:instream-foreign-object>
</fo:block>
]]></source>
<p>The resource-level attribute where the resource object will reside in the AFP output datastream.
The possible values for this are "inline", "print-file" and "external".
When no resource-level attribute is provided, resources are by default placed at "print-file" level.
When "external" is used a resource-group-file attribute must also be specified.</p>
<p></p>
</section>
</section>
</section>
<section id="rtf">
<title>RTF</title>

+ 5
- 0
src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler View File

@@ -0,0 +1,5 @@
org.apache.fop.render.afp.AFPImageHandlerRenderedImage
org.apache.fop.render.afp.AFPImageHandlerRawCCITTFax
org.apache.fop.render.afp.AFPImageHandlerRawStream
org.apache.fop.render.afp.AFPImageHandlerGraphics2D
org.apache.fop.render.afp.AFPImageHandlerXML

+ 194
- 0
src/java/org/apache/fop/afp/AFPBorderPainter.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.awt.geom.AffineTransform;

import org.apache.fop.fo.Constants;
import org.apache.fop.util.ColorUtil;

/**
* Handles the drawing of borders/lines in AFP
*/
public class AFPBorderPainter extends AbstractAFPPainter {

/**
* Main constructor
*
* @param paintingState the AFP painting state converter
* @param dataStream the AFP datastream
*/
public AFPBorderPainter(AFPPaintingState paintingState, DataStream dataStream) {
super(paintingState, dataStream);
}

/** {@inheritDoc} */
public void paint(PaintingInfo paintInfo) {
BorderPaintingInfo borderPaintInfo = (BorderPaintingInfo)paintInfo;
float w = borderPaintInfo.getX2() - borderPaintInfo.getX1();
float h = borderPaintInfo.getY2() - borderPaintInfo.getY1();
if ((w < 0) || (h < 0)) {
log.error("Negative extent received. Border won't be painted.");
return;
}

int pageWidth = dataStream.getCurrentPage().getWidth();
int pageHeight = dataStream.getCurrentPage().getHeight();
AFPUnitConverter unitConv = paintingState.getUnitConverter();
AffineTransform at = paintingState.getData().getTransform();

float x1 = unitConv.pt2units(borderPaintInfo.getX1());
float y1 = unitConv.pt2units(borderPaintInfo.getY1());
float x2 = unitConv.pt2units(borderPaintInfo.getX2());
float y2 = unitConv.pt2units(borderPaintInfo.getY2());

switch (paintingState.getRotation()) {
case 0:
x1 += at.getTranslateX();
y1 += at.getTranslateY();
x2 += at.getTranslateX();
y2 += at.getTranslateY();
break;
case 90:
x1 += at.getTranslateY();
y1 += (float) (pageWidth - at.getTranslateX());
x2 += at.getTranslateY();
y2 += (float) (pageWidth - at.getTranslateX());
break;
case 180:
x1 += (float) (pageWidth - at.getTranslateX());
y1 += (float) (pageHeight - at.getTranslateY());
x2 += (float) (pageWidth - at.getTranslateX());
y2 += (float) (pageHeight - at.getTranslateY());
break;
case 270:
x1 = (float) (pageHeight - at.getTranslateY());
y1 += (float) at.getTranslateX();
x2 += x1;
y2 += (float) at.getTranslateX();
break;
}

AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
lineDataInfo.setColor(borderPaintInfo.getColor());
lineDataInfo.setRotation(paintingState.getRotation());
lineDataInfo.x1 = Math.round(x1);
lineDataInfo.y1 = Math.round(y1);
if (borderPaintInfo.isHorizontal()) {
lineDataInfo.setThickness(Math.round(y2 - y1));
} else {
lineDataInfo.setThickness(Math.round(x2 - x1));
}

// handle border-*-style
switch (borderPaintInfo.getStyle()) {
case Constants.EN_DOUBLE:
if (borderPaintInfo.isHorizontal()) {
lineDataInfo.x2 = Math.round(x2);
lineDataInfo.y2 = lineDataInfo.y1;
dataStream.createLine(lineDataInfo);
lineDataInfo.y1 += Math.round((lineDataInfo.thickness / 3) * 2);
dataStream.createLine(lineDataInfo);
} else {
lineDataInfo.x2 = lineDataInfo.x1;
lineDataInfo.y2 = Math.round(y2);
dataStream.createLine(lineDataInfo);
lineDataInfo.x1 += Math.round((lineDataInfo.thickness / 3) * 2);
dataStream.createLine(lineDataInfo);
}
break;
case Constants.EN_DASHED:
int thick = lineDataInfo.thickness * 3;
if (borderPaintInfo.isHorizontal()) {
lineDataInfo.x2 = lineDataInfo.x1 + thick;
lineDataInfo.y2 = lineDataInfo.y1;
int ex2 = Math.round(x2);
while (lineDataInfo.x1 + thick < ex2) {
dataStream.createLine(lineDataInfo);
lineDataInfo.x1 += 2 * thick;
lineDataInfo.x2 = lineDataInfo.x1 + thick;
}
} else {
lineDataInfo.x2 = lineDataInfo.x1;
lineDataInfo.y2 = lineDataInfo.y1 + thick;
int ey2 = Math.round(y2);
while (lineDataInfo.y1 + thick < ey2) {
dataStream.createLine(lineDataInfo);
lineDataInfo.y1 += 2 * thick;
lineDataInfo.y2 = lineDataInfo.y1 + thick;
}
}
break;
case Constants.EN_DOTTED:
if (borderPaintInfo.isHorizontal()) {
lineDataInfo.x2 = lineDataInfo.x1 + lineDataInfo.thickness;
lineDataInfo.y2 = lineDataInfo.y1;
int ex2 = Math.round(x2);
while (lineDataInfo.x1 + lineDataInfo.thickness < ex2) {
dataStream.createLine(lineDataInfo);
lineDataInfo.x1 += 3 * lineDataInfo.thickness;
lineDataInfo.x2 = lineDataInfo.x1 + lineDataInfo.thickness;
}
} else {
lineDataInfo.x2 = lineDataInfo.x1;
lineDataInfo.y2 = lineDataInfo.y1 + lineDataInfo.thickness;
int ey2 = Math.round(y2);
while (lineDataInfo.y1 + lineDataInfo.thickness < ey2) {
dataStream.createLine(lineDataInfo);
lineDataInfo.y1 += 3 * lineDataInfo.thickness;
lineDataInfo.y2 = lineDataInfo.y1 + lineDataInfo.thickness;
}
}
break;
case Constants.EN_GROOVE:
case Constants.EN_RIDGE:
//TODO
lineDataInfo.x2 = Math.round(x2);
float colFactor = (borderPaintInfo.getStyle() == Constants.EN_GROOVE ? 0.4f : -0.4f);
float h3 = (y2 - y1) / 3;
lineDataInfo.color = ColorUtil.lightenColor(borderPaintInfo.getColor(), -colFactor);
lineDataInfo.thickness = Math.round(h3);
lineDataInfo.y1 = lineDataInfo.y2 = Math.round(y1);
dataStream.createLine(lineDataInfo);
lineDataInfo.color = borderPaintInfo.getColor();
lineDataInfo.y1 = lineDataInfo.y2 = Math.round(y1 + h3);
dataStream.createLine(lineDataInfo);
lineDataInfo.color = ColorUtil.lightenColor(borderPaintInfo.getColor(), colFactor);
lineDataInfo.y1 = lineDataInfo.y2 = Math.round(y1 + h3 + h3);
dataStream.createLine(lineDataInfo);
break;
case Constants.EN_HIDDEN:
break;
case Constants.EN_INSET:
case Constants.EN_OUTSET:
case Constants.EN_SOLID:
default:
if (borderPaintInfo.isHorizontal()) {
lineDataInfo.x2 = Math.round(x2);
lineDataInfo.y2 = lineDataInfo.y1;
} else {
lineDataInfo.x2 = lineDataInfo.x1;
lineDataInfo.y2 = Math.round(y2);
}
dataStream.createLine(lineDataInfo);
}
}

}

src/java/org/apache/fop/render/afp/modca/AFPConstants.java → src/java/org/apache/fop/afp/AFPConstants.java View File

@@ -17,7 +17,7 @@

/* $Id$ */

package org.apache.fop.render.afp.modca;
package org.apache.fop.afp;

/**
* Constants used by the AFP renderer.
@@ -34,4 +34,20 @@ public interface AFPConstants {
* The encoding to use to convert to ASCII
*/
String ASCII_ENCODING = "Cp1252";

/**
* The encoding to use to convert to US ASCII (7 bit)
*/
String US_ASCII_ENCODING = "US-ASCII";
/**
* The scaling of the default transform is set to
* approximately 72 user space coordinates per square inch
*/
int DPI_72 = 72;
/**
* 72dpi in millipoints
*/
int DPI_72_MPTS = DPI_72 * 1000;
}

+ 272
- 0
src/java/org/apache/fop/afp/AFPDataObjectFactory.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.awt.geom.Rectangle2D;

import org.apache.fop.afp.ioca.ImageContent;
import org.apache.fop.afp.modca.AbstractDataObject;
import org.apache.fop.afp.modca.AbstractNamedAFPObject;
import org.apache.fop.afp.modca.Document;
import org.apache.fop.afp.modca.GraphicsObject;
import org.apache.fop.afp.modca.ImageObject;
import org.apache.fop.afp.modca.IncludeObject;
import org.apache.fop.afp.modca.ObjectContainer;
import org.apache.fop.afp.modca.Overlay;
import org.apache.fop.afp.modca.PageSegment;
import org.apache.fop.afp.modca.Registry;
import org.apache.fop.afp.modca.ResourceObject;
import org.apache.fop.afp.modca.triplets.MappingOptionTriplet;
import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet;
import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;

/**
* Factory for high level data objects (Image/Graphics etc)
*/
public class AFPDataObjectFactory {

private final Factory factory;

/**
* Main constructor
*
* @param factory an object factory
*/
public AFPDataObjectFactory(Factory factory) {
this.factory = factory;
}

/**
* Creates and configures an ObjectContainer.
*
* @param dataObjectInfo the object container info
* @return a newly created Object Container
*/
public ObjectContainer createObjectContainer(AFPDataObjectInfo dataObjectInfo) {
ObjectContainer objectContainer = factory.createObjectContainer();

// set data object viewport (i.e. position, rotation, dimension, resolution)
objectContainer.setViewport(dataObjectInfo);

// set object classification
Registry.ObjectType objectType = dataObjectInfo.getObjectType();
AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
AFPResourceLevel resourceLevel = resourceInfo.getLevel();
final boolean dataInContainer = true;
final boolean containerHasOEG = resourceLevel.isInline();
final boolean dataInOCD = true;
objectContainer.setObjectClassification(
ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT,
objectType, dataInContainer, containerHasOEG, dataInOCD);

objectContainer.setData(dataObjectInfo.getData());
return objectContainer;
}

/**
* Creates and configures an IOCA Image Object.
*
* @param imageObjectInfo the image object info
* @return a newly created IOCA Image Object
*/
public ImageObject createImage(AFPImageObjectInfo imageObjectInfo) {
// IOCA bitmap image
ImageObject imageObj = factory.createImageObject();

// set data object viewport (i.e. position, rotation, dimension, resolution)
imageObj.setViewport(imageObjectInfo);

if (imageObjectInfo.hasCompression()) {
int compression = imageObjectInfo.getCompression();
switch (compression) {
case TIFFImage.COMP_FAX_G3_1D:
imageObj.setEncoding(ImageContent.COMPID_G3_MH);
break;
case TIFFImage.COMP_FAX_G3_2D:
imageObj.setEncoding(ImageContent.COMPID_G3_MR);
break;
case TIFFImage.COMP_FAX_G4_2D:
imageObj.setEncoding(ImageContent.COMPID_G3_MMR);
break;
default:
throw new IllegalStateException(
"Invalid compression scheme: " + compression);
}
}

if (imageObjectInfo.isColor()) {
imageObj.setIDESize((byte) 24);
} else {
imageObj.setIDESize((byte) imageObjectInfo.getBitsPerPixel());
}

imageObj.setData(imageObjectInfo.getData());

return imageObj;
}

/**
* Creates and returns a new graphics object.
*
* @param graphicsObjectInfo the graphics object info
* @return a new graphics object
*/
public GraphicsObject createGraphic(AFPGraphicsObjectInfo graphicsObjectInfo) {
// set newly created graphics object in g2d
GraphicsObject graphicsObj = factory.createGraphicsObject();

// set data object viewport (i.e. position, rotation, dimension, resolution)
graphicsObj.setViewport(graphicsObjectInfo);

AFPGraphics2D g2d = graphicsObjectInfo.getGraphics2D();
g2d.setGraphicsObject(graphicsObj);

// paint to graphics object
Graphics2DImagePainter painter = graphicsObjectInfo.getPainter();
Rectangle2D area = graphicsObjectInfo.getArea();
g2d.scale(1, -1);
g2d.translate(0, -area.getHeight());

painter.paint(g2d, area);

graphicsObj.setComplete(true);

// return painted graphics object
return graphicsObj;
}

/**
* Creates and returns a new include object.
*
* @param includeName the include name
* @param dataObjectInfo a data object info
*
* @return a new include object
*/
public IncludeObject createInclude(String includeName, AFPDataObjectInfo dataObjectInfo) {
IncludeObject includeObj = factory.createInclude(includeName);

if (dataObjectInfo instanceof AFPImageObjectInfo) {
// IOCA image object
includeObj.setObjectType(IncludeObject.TYPE_IMAGE);
} else if (dataObjectInfo instanceof AFPGraphicsObjectInfo) {
// graphics object
includeObj.setObjectType(IncludeObject.TYPE_GRAPHIC);
} else {
// object container
includeObj.setObjectType(IncludeObject.TYPE_OTHER);

// set mandatory object classification (type other)
Registry.ObjectType objectType = dataObjectInfo.getObjectType();
if (objectType != null) {
// set object classification
final boolean dataInContainer = true;
final boolean containerHasOEG = false; // environment parameters set in include
final boolean dataInOCD = true;
includeObj.setObjectClassification(
// object scope not defined
ObjectClassificationTriplet.CLASS_TIME_VARIANT_PRESENTATION_OBJECT,
objectType, dataInContainer, containerHasOEG, dataInOCD);
} else {
throw new IllegalStateException(
"Failed to set Object Classification Triplet on Object Container.");
}
}

AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo();

int xOffset = objectAreaInfo.getX();
int yOffset = objectAreaInfo.getY();
includeObj.setObjectAreaOffset(xOffset, yOffset);

int width = objectAreaInfo.getWidth();
int height = objectAreaInfo.getHeight();
includeObj.setObjectAreaSize(width, height);

int rotation = objectAreaInfo.getRotation();
includeObj.setObjectAreaOrientation(rotation);

int widthRes = objectAreaInfo.getWidthRes();
int heightRes = objectAreaInfo.getHeightRes();
includeObj.setMeasurementUnits(widthRes, heightRes);

includeObj.setMappingOption(MappingOptionTriplet.SCALE_TO_FIT);

return includeObj;
}

/**
* Creates a resource object wrapper for named includable data objects
*
* @param namedObj an named object
* @param resourceInfo resource information
* @param objectType the object type
* @return a new resource object wrapper
*/
public ResourceObject createResource(AbstractNamedAFPObject namedObj,
AFPResourceInfo resourceInfo, Registry.ObjectType objectType) {
ResourceObject resourceObj = null;
String resourceName = resourceInfo.getName();
if (resourceName != null) {
resourceObj = factory.createResource(resourceName);
} else {
resourceObj = factory.createResource();
}

if (namedObj instanceof Document) {
resourceObj.setType(ResourceObject.TYPE_DOCUMENT);
} else if (namedObj instanceof PageSegment) {
resourceObj.setType(ResourceObject.TYPE_PAGE_SEGMENT);
} else if (namedObj instanceof Overlay) {
resourceObj.setType(ResourceObject.TYPE_OVERLAY_OBJECT);
} else if (namedObj instanceof AbstractDataObject) {
AbstractDataObject dataObj = (AbstractDataObject)namedObj;
if (namedObj instanceof ObjectContainer) {
resourceObj.setType(ResourceObject.TYPE_OBJECT_CONTAINER);

// set object classification
final boolean dataInContainer = true;
final boolean containerHasOEG = false; // must be included
final boolean dataInOCD = true;
// mandatory triplet for object container
resourceObj.setObjectClassification(
ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT,
objectType, dataInContainer, containerHasOEG, dataInOCD);
} else if (namedObj instanceof ImageObject) {
// ioca image type
resourceObj.setType(ResourceObject.TYPE_IMAGE);
} else if (namedObj instanceof GraphicsObject) {
resourceObj.setType(ResourceObject.TYPE_GRAPHIC);
} else {
throw new UnsupportedOperationException(
"Unsupported resource object for data object type " + dataObj);
}
} else {
throw new UnsupportedOperationException(
"Unsupported resource object type " + namedObj);
}

// set the resource information/classification on the data object
resourceObj.setDataObject(namedObj);
return resourceObj;
}

}

+ 247
- 0
src/java/org/apache/fop/afp/AFPDataObjectInfo.java View File

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

/* $Id: $ */

package org.apache.fop.afp;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.modca.Registry;

/**
* A list of parameters associated with an AFP data objects
*/
public class AFPDataObjectInfo {
private static final Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");

/** the object area info */
private AFPObjectAreaInfo objectAreaInfo;

/** resource info */
private AFPResourceInfo resourceInfo;

/** the data object width */
private int dataWidth;

/** the data object height */
private int dataHeight;

/** the object registry mimetype */
private String mimeType;

/** the object data in a byte array */
private byte[] data;

/** the object data height resolution */
private int dataHeightRes;

/** the object data width resolution */
private int dataWidthRes;

/**
* Default constructor
*/
public AFPDataObjectInfo() {
}

/**
* Sets the image mime type
*
* @param mimeType the image mime type
*/
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}

/**
* Returns the mime type of this data object
*
* @return the mime type of this data object
*/
public String getMimeType() {
return mimeType;
}

/**
* Convenience method to return the object type
*
* @return the object type
*/
public Registry.ObjectType getObjectType() {
return Registry.getInstance().getObjectType(getMimeType());
}

/**
* Returns the resource level at which this data object should reside
*
* @return the resource level at which this data object should reside
*/
public AFPResourceInfo getResourceInfo() {
if (resourceInfo == null) {
this.resourceInfo = new AFPResourceInfo();
}
return resourceInfo;
}

/**
* Sets the resource level at which this object should reside
*
* @param resourceInfo the resource level at which this data object should reside
*/
public void setResourceInfo(AFPResourceInfo resourceInfo) {
this.resourceInfo = resourceInfo;
}

/**
* Sets the object area info
*
* @param objectAreaInfo the object area info
*/
public void setObjectAreaInfo(AFPObjectAreaInfo objectAreaInfo) {
this.objectAreaInfo = objectAreaInfo;
}

/**
* Returns the object area info
*
* @return the object area info
*/
public AFPObjectAreaInfo getObjectAreaInfo() {
return this.objectAreaInfo;
}

/**
* Returns the uri of this data object
*
* @return the uri of this data object
*/
public String getUri() {
return getResourceInfo().getUri();
}

/**
* Sets the data object uri
*
* @param uri the data object uri
*/
public void setUri(String uri) {
getResourceInfo().setUri(uri);
}

/**
* Returns the image data width
*
* @return the image data width
*/
public int getDataWidth() {
return dataWidth;
}

/**
* Sets the image data width
*
* @param imageDataWidth the image data width
*/
public void setDataWidth(int imageDataWidth) {
this.dataWidth = imageDataWidth;
}

/**
* Returns the image data height
*
* @return the image data height
*/
public int getDataHeight() {
return dataHeight;
}

/**
* Sets the image data height
*
* @param imageDataHeight the image data height
*/
public void setDataHeight(int imageDataHeight) {
this.dataHeight = imageDataHeight;
}

/**
* Returns the data height resolution
*
* @return the data height resolution
*/
public int getDataHeightRes() {
return this.dataHeightRes;
}

/**
* Sets the data width resolution
*
* @param dataWidthRes the data width resolution
*/
public void setDataHeightRes(int dataHeightRes) {
this.dataHeightRes = dataHeightRes;
}

/**
* Returns the data width resolution
*
* @return the data width resolution
*/
public int getDataWidthRes() {
return this.dataWidthRes;
}

/**
* Sets the data width resolution
*
* @param dataWidthRes the data width resolution
*/
public void setDataWidthRes(int dataWidthRes) {
this.dataWidthRes = dataWidthRes;
}

/**
* Sets the object data
*
* @param data the object data
*/
public void setData(byte[] data) {
this.data = data;
}

/**
* Returns the object data
*
* @return the object data
*/
public byte[] getData() {
return this.data;
}

/** {@inheritDoc} */
public String toString() {
return "AFPDataObjectInfo{"
+ "mimeType=" + mimeType
+ ", dataWidth=" + dataWidth
+ ", dataHeight=" + dataHeight
+ ", dataWidthRes=" + dataWidthRes
+ ", dataHeightRes=" + dataHeightRes
+ (objectAreaInfo != null ? ", objectAreaInfo=" + objectAreaInfo : "")
+ (resourceInfo != null ? ", resourceInfo=" + resourceInfo : "");
}
}

src/java/org/apache/fop/render/afp/AFPEventProducer.java → src/java/org/apache/fop/afp/AFPEventProducer.java View File

@@ -17,7 +17,7 @@

/* $Id$ */

package org.apache.fop.render.afp;
package org.apache.fop.afp;

import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.events.EventProducer;
@@ -55,9 +55,29 @@ public interface AFPEventProducer extends EventProducer {

/**
* Warn about using default font setup.
*
* @param source the event source
* @event.severity WARN
*/
void warnDefaultFontSetup(Object source);

/**
* Warn about a missing default "any" font configuration.
*
* @param source the event source
* @param style the font style
* @param weight the font weight
* @event.severity WARN
*/
void warnMissingDefaultFont(Object source, String style, int weight);

/**
* A character set encoding error occurred.
*
* @param source the event source
* @param charSetName the character set name
* @param encoding the encoding
* @event.severity ERROR
*/
void characterSetEncodingError(Object source, String charSetName, String encoding);
}

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

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<catalogue xml:lang="en">
<message key="org.apache.fop.afp.AFPEventProducer.warnDefaultFontSetup">No AFP fonts configured. Using default setup.</message>
<message key="org.apache.fop.afp.AFPEventProducer.warnMissingDefaultFont">No AFP default "any", {style}, {weight} font configured.</message>
<message key="org.apache.fop.afp.AFPEventProducer.characterSetEncodingError">An error occurred when attempting to encode character set {charSetName} with encoding scheme {encoding}.</message>
</catalogue>

+ 698
- 0
src/java/org/apache/fop/afp/AFPGraphics2D.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.io.IOException;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.goca.GraphicsSetLineType;
import org.apache.fop.afp.modca.GraphicsObject;
import org.apache.fop.afp.svg.AFPGraphicsConfiguration;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.NativeImageHandler;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.xmlgraphics.java2d.StrokingTextHandler;
import org.apache.xmlgraphics.java2d.TextHandler;
import org.apache.xmlgraphics.ps.ImageEncodingHelper;
import org.apache.xmlgraphics.util.MimeConstants;

/**
* This is a concrete implementation of <tt>AbstractGraphics2D</tt> (and
* therefore of <tt>Graphics2D</tt>) which is able to generate GOCA byte
* codes.
*
* @see org.apache.xmlgraphics.java2d.AbstractGraphics2D
*/
public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHandler {

private static final Log log = LogFactory.getLog(AFPGraphics2D.class);

private static final int X = 0;

private static final int Y = 1;

private static final int X1 = 0;

private static final int Y1 = 1;

private static final int X2 = 2;

private static final int Y2 = 3;

private static final int X3 = 4;

private static final int Y3 = 5;

/** graphics object */
private GraphicsObject graphicsObj = null;

/** Fallback text handler */
protected TextHandler fallbackTextHandler = new StrokingTextHandler();

/** Custom text handler */
protected TextHandler customTextHandler = null;

/** AFP resource manager */
private AFPResourceManager resourceManager = null;

/** AFP resource info */
private AFPResourceInfo resourceInfo = null;

/** Current AFP state */
private AFPPaintingState paintingState = null;

/** AFP graphics configuration */
private final AFPGraphicsConfiguration graphicsConfig = new AFPGraphicsConfiguration();

/** The AFP FontInfo */
private FontInfo fontInfo;

/**
* Main constructor
*
* @param textAsShapes
* if true, all text is turned into shapes in the convertion. No
* text is output.
* @param paintingState painting state
* @param resourceManager resource manager
* @param resourceInfo resource info
* @param fontInfo font info
*/
public AFPGraphics2D(boolean textAsShapes, AFPPaintingState paintingState,
AFPResourceManager resourceManager, AFPResourceInfo resourceInfo,
FontInfo fontInfo) {
super(textAsShapes);
this.paintingState = paintingState;
this.resourceManager = resourceManager;
this.resourceInfo = resourceInfo;
this.fontInfo = fontInfo;
}

/**
* Copy Constructor
*
* @param g2d
* a AFPGraphics2D whose properties should be copied
*/
public AFPGraphics2D(AFPGraphics2D g2d) {
super(g2d);
this.paintingState = g2d.paintingState;
this.resourceManager = g2d.resourceManager;
this.resourceInfo = g2d.resourceInfo;
this.fontInfo = g2d.fontInfo;

this.graphicsObj = g2d.graphicsObj;
this.fallbackTextHandler = g2d.fallbackTextHandler;
this.customTextHandler = g2d.customTextHandler;
}

/**
* Sets the AFP resource manager
*
* @param resourceManager the AFP resource manager
*/
public void setResourceManager(AFPResourceManager resourceManager) {
this.resourceManager = resourceManager;
}

/**
* Sets the AFP resource info
*
* @param resourceInfo the AFP resource info
*/
public void setResourceInfo(AFPResourceInfo resourceInfo) {
this.resourceInfo = resourceInfo;
}

/**
* Sets the GraphicContext
*
* @param gc
* GraphicContext to use
*/
public void setGraphicContext(GraphicContext gc) {
this.gc = gc;
}

/**
* Apply the stroke to the AFP graphics object.
* This takes the java stroke and outputs the appropriate settings
* to the AFP graphics object so that the stroke attributes are handled.
*
* @param stroke the java stroke
*/
protected void applyStroke(Stroke stroke) {
if (stroke instanceof BasicStroke) {
BasicStroke basicStroke = (BasicStroke) stroke;

// set line width
float lineWidth = basicStroke.getLineWidth();
graphicsObj.setLineWidth(Math.round(lineWidth / 2));

// set line type/style (note: this is an approximation at best!)
float[] dashArray = basicStroke.getDashArray();
if (paintingState.setDashArray(dashArray)) {
byte type = GraphicsSetLineType.DEFAULT; // normally SOLID
if (dashArray != null) {
type = GraphicsSetLineType.DOTTED; // default to plain DOTTED if dashed line
// float offset = basicStroke.getDashPhase();
if (dashArray.length == 2) {
if (dashArray[0] < dashArray[1]) {
type = GraphicsSetLineType.SHORT_DASHED;
} else if (dashArray[0] > dashArray[1]) {
type = GraphicsSetLineType.LONG_DASHED;
}
} else if (dashArray.length == 4) {
if (dashArray[0] > dashArray[1]
&& dashArray[2] < dashArray[3]) {
type = GraphicsSetLineType.DASH_DOT;
} else if (dashArray[0] < dashArray[1]
&& dashArray[2] < dashArray[3]) {
type = GraphicsSetLineType.DOUBLE_DOTTED;
}
} else if (dashArray.length == 6) {
if (dashArray[0] > dashArray[1]
&& dashArray[2] < dashArray[3]
&& dashArray[4] < dashArray[5]) {
type = GraphicsSetLineType.DASH_DOUBLE_DOTTED;
}
}
}
graphicsObj.setLineType(type);
}
} else {
log.warn("Unsupported Stroke: " + stroke.getClass().getName());
}
}

/**
* Apply the java paint to the AFP.
* This takes the java paint sets up the appropriate AFP commands
* for the drawing with that paint.
* Currently this supports the gradients and patterns from batik.
*
* @param paint the paint to convert to AFP
* @param fill true if the paint should be set for filling
* @return true if the paint is handled natively, false if the paint should be rasterized
*/
private boolean applyPaint(Paint paint, boolean fill) {
if (paint instanceof Color) {
return true;
}
log.debug("NYI: applyPaint() " + paint + " fill=" + fill);
if (paint instanceof TexturePaint) {
// TexturePaint texturePaint = (TexturePaint)paint;
// BufferedImage bufferedImage = texturePaint.getImage();
// AffineTransform at = paintingState.getTransform();
// int x = (int)Math.round(at.getTranslateX());
// int y = (int)Math.round(at.getTranslateY());
// drawImage(bufferedImage, x, y, null);
}
return false;
}


/**
* Handle the Batik drawing event
*
* @param shape
* the shape to draw
* @param fill
* true if the shape is to be drawn filled
*/
private void doDrawing(Shape shape, boolean fill) {
if (!fill) {
graphicsObj.newSegment();
}

graphicsObj.setColor(gc.getColor());

applyPaint(gc.getPaint(), fill);

if (fill) {
graphicsObj.beginArea();
} else {
applyStroke(gc.getStroke());
}

AffineTransform trans = gc.getTransform();
PathIterator iter = shape.getPathIterator(trans);
if (shape instanceof Line2D) {
double[] dstPts = new double[6];
iter.currentSegment(dstPts);
int[] coords = new int[4];
coords[X1] = (int) Math.round(dstPts[X]);
coords[Y1] = (int) Math.round(dstPts[Y]);
iter.next();
iter.currentSegment(dstPts);
coords[X2] = (int) Math.round(dstPts[X]);
coords[Y2] = (int) Math.round(dstPts[Y]);
graphicsObj.addLine(coords);
} else if (shape instanceof Rectangle2D) {
double[] dstPts = new double[6];
iter.currentSegment(dstPts);
int[] coords = new int[4];
coords[X2] = (int) Math.round(dstPts[X]);
coords[Y2] = (int) Math.round(dstPts[Y]);
iter.next();
iter.next();
iter.currentSegment(dstPts);
coords[X1] = (int) Math.round(dstPts[X]);
coords[Y1] = (int) Math.round(dstPts[Y]);
graphicsObj.addBox(coords);
} else if (shape instanceof Ellipse2D) {
double[] dstPts = new double[6];
Ellipse2D elip = (Ellipse2D) shape;
double scale = trans.getScaleX();
double radiusWidth = elip.getWidth() / 2;
double radiusHeight = elip.getHeight() / 2;
graphicsObj.setArcParams(
(int)Math.round(radiusWidth * scale),
(int)Math.round(radiusHeight * scale),
0,
0
);
double[] srcPts = new double[] {elip.getCenterX(), elip.getCenterY()};
trans.transform(srcPts, 0, dstPts, 0, 1);
final int mh = 1;
final int mhr = 0;
graphicsObj.addFullArc(
(int)Math.round(dstPts[X]),
(int)Math.round(dstPts[Y]),
mh,
mhr
);
} else {
processPathIterator(iter);
}

if (fill) {
graphicsObj.endArea();
}
}

/**
* Processes a path iterator generating the necessary painting operations.
*
* @param iter PathIterator to process
*/
private void processPathIterator(PathIterator iter) {
double[] dstPts = new double[6];
for (int[] openingCoords = new int[2]; !iter.isDone(); iter.next()) {
switch (iter.currentSegment(dstPts)) {
case PathIterator.SEG_LINETO:
graphicsObj.addLine(new int[] {
(int)Math.round(dstPts[X]),
(int)Math.round(dstPts[Y])
}, true);
break;
case PathIterator.SEG_QUADTO:
graphicsObj.addFillet(new int[] {
(int)Math.round(dstPts[X1]),
(int)Math.round(dstPts[Y1]),
(int)Math.round(dstPts[X2]),
(int)Math.round(dstPts[Y2])
}, true);
break;
case PathIterator.SEG_CUBICTO:
graphicsObj.addFillet(new int[] {
(int)Math.round(dstPts[X1]),
(int)Math.round(dstPts[Y1]),
(int)Math.round(dstPts[X2]),
(int)Math.round(dstPts[Y2]),
(int)Math.round(dstPts[X3]),
(int)Math.round(dstPts[Y3])
}, true);
break;
case PathIterator.SEG_MOVETO:
openingCoords = new int[] {
(int)Math.round(dstPts[X]),
(int)Math.round(dstPts[Y])
};
graphicsObj.setCurrentPosition(openingCoords);
break;
case PathIterator.SEG_CLOSE:
graphicsObj.addLine(openingCoords, true);
break;
default:
log.debug("Unrecognised path iterator type");
break;
}
}
}

/** {@inheritDoc} */
public void draw(Shape shape) {
log.debug("draw() shape=" + shape);
doDrawing(shape, false);
}

/** {@inheritDoc} */
public void fill(Shape shape) {
log.debug("fill() shape=" + shape);
doDrawing(shape, true);
}

/**
* Central handler for IOExceptions for this class.
*
* @param ioe
* IOException to handle
*/
public void handleIOException(IOException ioe) {
// TODO Surely, there's a better way to do this.
log.error(ioe.getMessage());
ioe.printStackTrace();
}

/** {@inheritDoc} */
public void drawString(String str, float x, float y) {
try {
if (customTextHandler != null && !textAsShapes) {
customTextHandler.drawString(this, str, x, y);
} else {
fallbackTextHandler.drawString(this, str, x, y);
}
} catch (IOException ioe) {
handleIOException(ioe);
}
}

/** {@inheritDoc} */
public GraphicsConfiguration getDeviceConfiguration() {
return graphicsConfig;
}

/** {@inheritDoc} */
public Graphics create() {
return new AFPGraphics2D(this);
}

/** {@inheritDoc} */
public void dispose() {
this.graphicsObj = null;
}

/** {@inheritDoc} */
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), observer);
}

private BufferedImage buildBufferedImage(Dimension size) {
return new BufferedImage(size.width, size.height,
BufferedImage.TYPE_INT_ARGB);
}

private AFPImageObjectInfo createImageObjectInfo(
RenderedImage img, int x, int y, int width, int height) throws IOException {
ImageInfo imageInfo = new ImageInfo(null, "image/unknown");
ImageSize size = new ImageSize(img.getWidth(), img.getHeight(), 72);
imageInfo.setSize(size);

ImageRendered imageRendered = new ImageRendered(imageInfo, img, null);
RenderedImage renderedImage = imageRendered.getRenderedImage();

// create image object info
AFPImageObjectInfo imageObjectInfo = new AFPImageObjectInfo();

imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45);

int bitsPerPixel = paintingState.getBitsPerPixel();
imageObjectInfo.setBitsPerPixel(bitsPerPixel);

imageObjectInfo.setResourceInfo(resourceInfo);

int dataHeight = renderedImage.getHeight();
imageObjectInfo.setDataHeight(dataHeight);

int dataWidth = renderedImage.getWidth();
imageObjectInfo.setDataWidth(dataWidth);

boolean colorImages = paintingState.isColorImages();
imageObjectInfo.setColor(colorImages);

ByteArrayOutputStream boas = new ByteArrayOutputStream();
ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, boas);
byte[] imageData = boas.toByteArray();

// convert to grayscale
if (!colorImages) {
boas.reset();
imageObjectInfo.setBitsPerPixel(bitsPerPixel);
ImageEncodingHelper.encodeRGBAsGrayScale(
imageData, dataWidth, dataHeight, bitsPerPixel, boas);
imageData = boas.toByteArray();
}
imageObjectInfo.setData(imageData);

if (imageInfo != null) {
imageObjectInfo.setUri(imageInfo.getOriginalURI());
}

// create object area info
AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo();
objectAreaInfo.setX(x);
objectAreaInfo.setY(y);
objectAreaInfo.setWidth(width);
objectAreaInfo.setHeight(height);

int resolution = paintingState.getResolution();
objectAreaInfo.setWidthRes(resolution);
objectAreaInfo.setHeightRes(resolution);

imageObjectInfo.setObjectAreaInfo(objectAreaInfo);

return imageObjectInfo;
}

/**
* Draws an AWT image into a BufferedImage using an AWT Graphics2D implementation
*
* @param img the AWT image
* @param bufferedImage the AWT buffered image
* @param width the image width
* @param height the image height
* @param observer the image observer
* @return true if the image was drawn
*/
private boolean drawBufferedImage(Image img, BufferedImage bufferedImage,
int width, int height, ImageObserver observer) {

java.awt.Graphics2D g2d = bufferedImage.createGraphics();
try {
g2d.setComposite(AlphaComposite.SrcOver);

Color color = new Color(1, 1, 1, 0);
g2d.setBackground(color);
g2d.setPaint(color);

g2d.fillRect(0, 0, width, height);

int imageWidth = bufferedImage.getWidth();
int imageHeight = bufferedImage.getHeight();
Rectangle clipRect = new Rectangle(0, 0, imageWidth, imageHeight);
g2d.clip(clipRect);

g2d.setComposite(gc.getComposite());

return g2d.drawImage(img, 0, 0, imageWidth, imageHeight, observer);
} finally {
g2d.dispose(); //drawn so dispose immediately to free system resource
}
}

/** {@inheritDoc} */
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer) {

// draw with AWT Graphics2D
Dimension imageSize = new Dimension(width, height);
BufferedImage bufferedImage = buildBufferedImage(imageSize);

boolean drawn = drawBufferedImage(img, bufferedImage, width, height, observer);
if (drawn) {
AffineTransform at = gc.getTransform();
float[] srcPts = new float[] {x, y};
float[] dstPts = new float[srcPts.length];
at.transform(srcPts, 0, dstPts, 0, 1);
x = Math.round(dstPts[X]);
y = Math.round(dstPts[Y]);
try {
// get image object info
AFPImageObjectInfo imageObjectInfo
= createImageObjectInfo(bufferedImage, x, y, width, height);

// create image resource
resourceManager.createObject(imageObjectInfo);
return true;
} catch (IOException ioe) {
handleIOException(ioe);
}
}
return false;
}

/** {@inheritDoc} */
public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
int imgWidth = img.getWidth();
int imgHeight = img.getHeight();

AffineTransform at = paintingState.getData().getTransform();
AffineTransform gat = gc.getTransform();
int graphicsObjectHeight
= graphicsObj.getObjectEnvironmentGroup().getObjectAreaDescriptor().getHeight();
int x = (int)Math.round(at.getTranslateX() + gat.getTranslateX());
int y = (int)Math.round(at.getTranslateY() - (gat.getTranslateY() - graphicsObjectHeight));
int width = (int)Math.round(imgWidth * gat.getScaleX());
int height = (int)Math.round(imgHeight * -gat.getScaleY());
try {
// get image object info
AFPImageObjectInfo imageObjectInfo
= createImageObjectInfo(img, x, y, width, height);
// create image resource
resourceManager.createObject(imageObjectInfo);
} catch (IOException ioe) {
handleIOException(ioe);
}
}

/**
* Sets a custom TextHandler implementation that is responsible for painting
* text. The default TextHandler paints all text as shapes. A custom
* implementation can implement text painting using text painting operators.
*
* @param handler
* the custom TextHandler implementation
*/
public void setCustomTextHandler(TextHandler handler) {
this.customTextHandler = handler;
}

/**
* Returns the GOCA graphics object
*
* @return the GOCA graphics object
*/
public GraphicsObject getGraphicsObject() {
return this.graphicsObj;
}

/**
* Sets the GOCA graphics object
*
* @param obj the GOCA graphics object
*/
public void setGraphicsObject(GraphicsObject obj) {
this.graphicsObj = obj;
}

/**
* Sets the AFP painting state
*
* @param paintingState the AFP painting state
*/
public void setPaintingState(AFPPaintingState paintingState) {
this.paintingState = paintingState;
}

/**
* Returns the AFP painting state
*
* @return the AFP painting state
*/
public AFPPaintingState getPaintingState() {
return this.paintingState;
}

/**
* Sets the FontInfo
*
* @param the FontInfo
*/
public void setFontInfo(FontInfo fontInfo) {
this.fontInfo = fontInfo;
}

/**
* Returns the FontInfo
*
* @return the FontInfo
*/
public FontInfo getFontInfo() {
return this.fontInfo;
}

/** {@inheritDoc} */
public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
log.debug("drawRenderableImage() NYI: img=" + img + ", xform=" + xform);
}

/** {@inheritDoc} */
public FontMetrics getFontMetrics(Font f) {
log.debug("getFontMetrics() NYI: f=" + f);
return null;
}

/** {@inheritDoc} */
public void setXORMode(Color col) {
log.debug("setXORMode() NYI: col=" + col);
}

/** {@inheritDoc} */
public void addNativeImage(org.apache.xmlgraphics.image.loader.Image image,
float x, float y, float width, float height) {
log.debug("NYI: addNativeImage() "+ "image=" + image
+ ",x=" + x + ",y=" + y + ",width=" + width + ",height=" + height);
}

/** {@inheritDoc} */
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
log.debug("copyArea() NYI: ");
}
}

+ 109
- 0
src/java/org/apache/fop/afp/AFPGraphicsObjectInfo.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.afp;

import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;

import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
import org.apache.xmlgraphics.util.MimeConstants;

/**
* A graphics object info which contains necessary painting objects
*/
public class AFPGraphicsObjectInfo extends AFPDataObjectInfo {

/** the graphics object painter implementation */
private Graphics2DImagePainter painter;

/** the graphics object area */
private Rectangle2D area;

/** the AFP graphics 2d implementation */
private AFPGraphics2D g2d;

/**
* Returns the graphics painter
*
* @return the graphics painter
*/
public Graphics2DImagePainter getPainter() {
return this.painter;
}

/**
* Sets the graphics painter
*
* @param graphicsPainter the graphics painter
*/
public void setPainter(Graphics2DImagePainter graphicsPainter) {
this.painter = graphicsPainter;
}

/**
* Returns the graphics area
*
* @return the graphics area
*/
public Rectangle2D getArea() {
AFPObjectAreaInfo objectAreaInfo = getObjectAreaInfo();
int width = objectAreaInfo.getWidth();
int height = objectAreaInfo.getHeight();
return new Rectangle(width, height);
}

/**
* Sets the graphics area area
*
* @param area the graphics object area
*/
public void setArea(Rectangle2D area) {
this.area = area;
}

/**
* Sets the AFP graphics 2D implementation
*
* @param g2d the AFP graphics 2D implementation
*/
public void setGraphics2D(AFPGraphics2D g2d) {
this.g2d = g2d;
}

/**
* Returns the AFP graphics 2D implementation
*
* @return the AFP graphics 2D implementation
*/
public AFPGraphics2D getGraphics2D() {
return this.g2d;
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsObjectInfo{" + super.toString() + "}";
}

/** {@inheritDoc} */
public String getMimeType() {
return MimeConstants.MIME_SVG;
}

}

+ 115
- 0
src/java/org/apache/fop/afp/AFPImageObjectInfo.java View File

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

/* $Id: $ */

package org.apache.fop.afp;


/**
* A list of parameters associated with an image
*/
public class AFPImageObjectInfo extends AFPDataObjectInfo {

/** number of bits per pixel used */
private int bitsPerPixel;

/** is this a color image? */
private boolean color;

/** compression type if any */
private int compression = -1;

/**
* Default constructor
*/
public AFPImageObjectInfo() {
super();
}

/**
* Sets the number of bits per pixel
*
* @param bitsPerPixel the number of bits per pixel
*/
public void setBitsPerPixel(int bitsPerPixel) {
this.bitsPerPixel = bitsPerPixel;
}

/**
* Sets if this image is color
*
* @param color true if this is a color image
*/
public void setColor(boolean color) {
this.color = color;
}

/**
* Returns the number of bits used per pixel
*
* @return the number of bits used per pixel
*/
public int getBitsPerPixel() {
return bitsPerPixel;
}

/**
* Returns true if this is a color image
*
* @return true if this is a color image
*/
public boolean isColor() {
return color;
}

/**
* Returns true if this image uses compression
*
* @return true if this image uses compression
*/
public boolean hasCompression() {
return compression > -1;
}

/**
* Returns the compression type
*
* @return the compression type
*/
public int getCompression() {
return compression;
}

/**
* Sets the compression used with this image
*
* @param compression the type of compression used with this image
*/
public void setCompression(int compression) {
this.compression = compression;
}

/** {@inheritDoc} */
public String toString() {
return "AFPImageObjectInfo{" + super.toString()
+ ", compression=" + compression
+ ", color=" + color
+ ", bitsPerPixel=" + bitsPerPixel
+ "}";
}
}

+ 192
- 0
src/java/org/apache/fop/afp/AFPLineDataInfo.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.awt.Color;

/** Line data information */
public class AFPLineDataInfo {

/** the x1 coordinate */
int x1;

/** the y1 coordinate */
int y1;

/** the x2 coordinate */
int x2;

/** the y2 coordinate */
int y2;

/** the thickness */
int thickness;

/** the painting color */
Color color;

/** the rotation */
int rotation = 0;

/**
* Default constructor
*/
public AFPLineDataInfo() {
}

/**
* Returns the X1 coordinate
*
* @return the X1 coordinate
*/
public int getX1() {
return x1;
}

/**
* Sets the X1 coordinate
*
* @param x1 the X1 coordinate
*/
public void setX1(int x1) {
this.x1 = x1;
}

/**
* Returns the Y1 coordinate
*
* @return the Y1 coordinate
*/
public int getY1() {
return y1;
}

/**
* Sets the Y1 coordinate
*
* @param y1 the Y1 coordinate
*/
public void setY1(int y1) {
this.y1 = y1;
}

/**
* Returns the X2 coordinate
*
* @return the X2 coordinate
*/
public int getX2() {
return x2;
}

/**
* Sets the X2 coordinate
*
* @param x2 the X2 coordinate
*/
public void setX2(int x2) {
this.x2 = x2;
}

/**
* Returns the Y2 coordinate
*
* @return the Y2 coordinate
*/
public int getY2() {
return y2;
}

/**
* Sets the Y2 coordinate
*
* @param y2 the Y2 coordinate
*/
public void setY2(int y2) {
this.y2 = y2;
}

/**
* Returns the line thickness
*
* @return the line thickness
*/
public int getThickness() {
return thickness;
}

/**
* Sets the line thickness
*
* @param thickness the line thickness
*/
public void setThickness(int thickness) {
this.thickness = thickness;
}

/**
* Returns line color
*
* @return the line color
*/
public Color getColor() {
return color;
}

/**
* Sets the line color
*
* @param color the line color
*/
public void setColor(Color color) {
this.color = color;
}

/**
* Returns line rotation
*
* @return the line rotation
*/
public int getRotation() {
return rotation;
}

/**
* Sets the line rotation
*
* @param rotation the line rotation
*/
public void setRotation(int rotation) {
this.rotation = rotation;
}

/** {@inheritDoc} */
public String toString() {
return "AFPLineDataInfo{x1=" + x1
+ ", y1=" + y1
+ ", x2=" + x2
+ ", y2=" + y2
+ ", thickness=" + thickness
+ ", color=" + color
+ ", rotation=" + rotation
+ "}";
}

}

+ 172
- 0
src/java/org/apache/fop/afp/AFPObjectAreaInfo.java View File

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

/* $Id$ */

package org.apache.fop.afp;

/**
* A common class used to convey locations,
* dimensions and resolutions of data objects.
*/
public class AFPObjectAreaInfo {
private int x;
private int y;
private int width;
private int height;
private int widthRes;
private int heightRes;
private int rotation = 0;

/**
* Sets the x position of the data object
*
* @param x the x position of the data object
*/
public void setX(int x) {
this.x = x;
}

/**
* Sets the y position of the data object
*
* @param y the y position of the data object
*/
public void setY(int y) {
this.y = y;
}

/**
* Sets the data object width
*
* @param width the width of the data object
*/
public void setWidth(int width) {
this.width = width;
}

/**
* Sets the data object height
*
* @param height the height of the data object
*/
public void setHeight(int height) {
this.height = height;
}

/**
* Sets the width resolution
*
* @param widthRes the width resolution
*/
public void setWidthRes(int widthRes) {
this.widthRes = widthRes;
}

/**
* Sets the height resolution
*
* @param heightRes the height resolution
*/
public void setHeightRes(int heightRes) {
this.heightRes = heightRes;
}

/**
* Returns the x coordinate of this data object
*
* @return the x coordinate of this data object
*/
public int getX() {
return x;
}

/**
* Returns the y coordinate of this data object
*
* @return the y coordinate of this data object
*/
public int getY() {
return y;
}

/**
* Returns the width of this data object
*
* @return the width of this data object
*/
public int getWidth() {
return width;
}

/**
* Returns the height of this data object
*
* @return the height of this data object
*/
public int getHeight() {
return height;
}

/**
* Returns the width resolution of this data object
*
* @return the width resolution of this data object
*/
public int getWidthRes() {
return widthRes;
}

/**
* Returns the height resolution of this data object
*
* @return the height resolution of this data object
*/
public int getHeightRes() {
return heightRes;
}

/**
* Returns the rotation of this data object
*
* @return the rotation of this data object
*/
public int getRotation() {
return rotation;
}

/**
* Sets the data object rotation
*
* @param rotation the data object rotation
*/
public void setRotation(int rotation) {
this.rotation = rotation;
}

/** {@inheritDoc} */
public String toString() {
return "x=" + x
+ ", y=" + y
+ ", width=" + width
+ ", height=" + height
+ ", widthRes=" + widthRes
+ ", heightRes=" + heightRes
+ ", rotation=" + rotation;
}

}

+ 495
- 0
src/java/org/apache/fop/afp/AFPPaintingState.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.fonts.AFPPageFonts;
import org.apache.fop.util.AbstractPaintingState;

/**
* This keeps information about the current painting state when writing to an AFP datastream.
*/
public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
implements Cloneable {

private static final long serialVersionUID = 8206711712452344473L;

private static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");

/** the portrait rotation */
private int portraitRotation = 0;

/** the landscape rotation */
private int landscapeRotation = 270;

/** color image support */
private boolean colorImages = false;

/** images are supported in this AFP environment */
private boolean nativeImagesSupported = false;

/** default value for image depth */
private int bitsPerPixel = 8;

/** the output resolution */
private int resolution = 240; // 240 dpi

/** the current page */
private AFPPagePaintingState pagePaintingState = new AFPPagePaintingState();

// /** reference orientation */
// private int orientation = 0;

/** a unit converter */
private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this);

/**
* Sets the rotation to be used for portrait pages, valid values are 0
* (default), 90, 180, 270.
*
* @param rotation
* The rotation in degrees.
*/
public void setPortraitRotation(int rotation) {
if (rotation == 0 || rotation == 90 || rotation == 180
|| rotation == 270) {
portraitRotation = rotation;
} else {
throw new IllegalArgumentException(
"The portrait rotation must be one"
+ " of the values 0, 90, 180, 270");

}
}

/**
* Returns the rotation to be used for portrait pages
*
* @return the rotation to be used for portrait pages
*/
protected int getPortraitRotation() {
return this.portraitRotation;
}

/**
* Sets the rotation to be used for landscape pages, valid values are 0, 90,
* 180, 270 (default).
*
* @param rotation
* The rotation in degrees.
*/
public void setLandscapeRotation(int rotation) {
if (rotation == 0 || rotation == 90 || rotation == 180
|| rotation == 270) {
landscapeRotation = rotation;
} else {
throw new IllegalArgumentException(
"The landscape rotation must be one"
+ " of the values 0, 90, 180, 270");
}
}

/**
* Returns the landscape rotation
*
* @return the landscape rotation
*/
protected int getLandscapeRotation() {
return this.landscapeRotation;
}

/**
* Sets the number of bits used per pixel
*
* @param bitsPerPixel
* number of bits per pixel
*/
public void setBitsPerPixel(int bitsPerPixel) {
switch (bitsPerPixel) {
case 1:
case 4:
case 8:
this.bitsPerPixel = bitsPerPixel;
break;
default:
log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
this.bitsPerPixel = 8;
break;
}
}

/**
* Returns the number of bits per pixel
*
* @return the number of bits per pixel
*/
public int getBitsPerPixel() {
return this.bitsPerPixel;
}

/**
* Sets whether images are color or not
*
* @param colorImages
* color image output
*/
public void setColorImages(boolean colorImages) {
this.colorImages = colorImages;
}

/**
* Returns true if color images are to be used
*
* @return true if color images are to be used
*/
public boolean isColorImages() {
return this.colorImages;
}

/**
* Sets whether images are natively supported or not in the AFP environment
*
* @param nativeImagesSupported true if images are natively supported in this AFP environment
*/
public void setNativeImagesSupported(boolean nativeImagesSupported) {
this.nativeImagesSupported = nativeImagesSupported;
}

/**
* Returns true if images are supported natively in this AFP environment
*
* @return true if images are supported natively in this AFP environment
*/
public boolean isNativeImagesSupported() {
return this.nativeImagesSupported;
}

/**
* Sets the output/device resolution
*
* @param resolution
* the output resolution (dpi)
*/
public void setResolution(int resolution) {
if (log.isDebugEnabled()) {
log.debug("renderer-resolution set to: " + resolution + "dpi");
}
this.resolution = resolution;
}

/**
* Returns the output/device resolution.
*
* @return the resolution in dpi
*/
public int getResolution() {
return this.resolution;
}

/** {@inheritDoc} */
protected AbstractData instantiateData() {
return new AFPData();
}

/** {@inheritDoc} */
protected AbstractPaintingState instantiate() {
return new AFPPaintingState();
}

/**
* Returns the painting state of the current page
*
* @return the painting state of the current page
*/
protected AFPPagePaintingState getPagePaintingState() {
return this.pagePaintingState;
}

/**
* Gets the current page fonts
*
* @return the current page fonts
*/
public AFPPageFonts getPageFonts() {
return pagePaintingState.getFonts();
}

/**
* Sets the page width
*
* @param pageWidth the page width
*/
public void setPageWidth(int pageWidth) {
pagePaintingState.setWidth(pageWidth);
}

/**
* Returns the page width
*
* @return the page width
*/
public int getPageWidth() {
return pagePaintingState.getWidth();
}

/**
* Sets the page height
*
* @param pageHeight the page height
*/
public void setPageHeight(int pageHeight) {
pagePaintingState.setHeight(pageHeight);
}

/**
* Returns the page height
*
* @return the page height
*/
public int getPageHeight() {
return pagePaintingState.getHeight();
}

/**
* Returns the page rotation
*
* @return the page rotation
*/
public int getPageRotation() {
return pagePaintingState.getOrientation();
}

/**
* Sets the uri of the current image
*
* @param uri the uri of the current image
*/
public void setImageUri(String uri) {
((AFPData)getData()).imageUri = uri;
}

/**
* Gets the uri of the current image
*
* @return the uri of the current image
*/
public String getImageUri() {
return ((AFPData)getData()).imageUri;
}

/**
* Returns the currently derived rotation
*
* @return the currently derived rotation
*/
public int getRotation() {
return getData().getDerivedRotation();
}

/**
* Returns the unit converter
*
* @return the unit converter
*/
public AFPUnitConverter getUnitConverter() {
return this.unitConv;
}

/** {@inheritDoc} */
public Object clone() {
AFPPaintingState paintingState = (AFPPaintingState)super.clone();
paintingState.pagePaintingState = (AFPPagePaintingState)this.pagePaintingState.clone();
paintingState.portraitRotation = this.portraitRotation;
paintingState.landscapeRotation = this.landscapeRotation;
paintingState.bitsPerPixel = this.bitsPerPixel;
paintingState.colorImages = this.colorImages;
paintingState.resolution = this.resolution;
return paintingState;
}

/** {@inheritDoc} */
public String toString() {
return "AFPPaintingState{" + "portraitRotation=" + portraitRotation
+ ", landscapeRotation=" + landscapeRotation
+ ", colorImages=" + colorImages
+ ", bitsPerPixel=" + bitsPerPixel
+ ", resolution=" + resolution
+ ", pageState=" + pagePaintingState
+ super.toString()
+ "}";
}

/**
* Page level state data
*/
private class AFPPagePaintingState implements Cloneable {
/** page width */
private int width = 0;

/** page height */
private int height = 0;

/** page fonts */
private AFPPageFonts fonts = new AFPPageFonts();

/** page font count */
private int fontCount = 0;

/** page orientation */
private int orientation = 0;

/**
* Returns the page width
*
* @return the page width
*/
protected int getWidth() {
return width;
}

/**
* Sets the page width
*
* @param width the page width
*/
protected void setWidth(int width) {
this.width = width;
}

/**
* Returns the page height
*
* @return the page height
*/
protected int getHeight() {
return height;
}

/**
* Sets the page height
*
* @param height the page height
*/
protected void setHeight(int height) {
this.height = height;
}

/**
* Returns the page fonts
*
* @return the page fonts
*/
protected AFPPageFonts getFonts() {
return fonts;
}

/**
* Sets the current page fonts
*
* @param fonts the current page fonts
*/
protected void setFonts(AFPPageFonts fonts) {
this.fonts = fonts;
}

/**
* Increments and returns the current page font count
*
* @return increment and return the current page font count
*/
protected int incrementFontCount() {
return ++fontCount;
}

/**
* Returns the current page orientation
*
* @return the current page orientation
*/
protected int getOrientation() {
return orientation;
}

/**
* Sets the current page orientation
*
* @param orientation the current page orientation
*/
protected void setOrientation(int orientation) {
this.orientation = orientation;
}

/** {@inheritDoc} */
public Object clone() {
AFPPagePaintingState state = new AFPPagePaintingState();
state.width = this.width;
state.height = this.height;
state.orientation = this.orientation;
state.fonts = new AFPPageFonts(this.fonts);
state.fontCount = this.fontCount;
return state;
}

/** {@inheritDoc} */
public String toString() {
return "AFPPagePaintingState{width=" + width
+ ", height=" + height
+ ", orientation=" + orientation
+ ", fonts=" + fonts
+ ", fontCount=" + fontCount
+ "}";
}
}

/**
* Block level state data
*/
private class AFPData extends org.apache.fop.util.AbstractPaintingState.AbstractData {
private static final long serialVersionUID = -1789481244175275686L;

/** The current fill status */
private boolean filled = false;

private String imageUri = null;

/** {@inheritDoc} */
public Object clone() {
AFPData obj = (AFPData)super.clone();
obj.filled = this.filled;
obj.imageUri = this.imageUri;
return obj;
}

/** {@inheritDoc} */
public String toString() {
return "AFPData{" + super.toString()
+ ", filled=" + filled
+ ", imageUri=" + imageUri
+ "}";
}

/** {@inheritDoc} */
protected AbstractData instantiate() {
return new AFPData();
}
}

}

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

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

/* $Id$ */

package org.apache.fop.afp;

import java.awt.geom.AffineTransform;


/**
* A painter of rectangles in AFP
*/
public class AFPRectanglePainter extends AbstractAFPPainter {

/**
* Main constructor
*
* @param paintingState the AFP painting state
* @param dataStream the AFP datastream
*/
public AFPRectanglePainter(AFPPaintingState paintingState, DataStream dataStream) {
super(paintingState, dataStream);
}

/** {@inheritDoc} */
public void paint(PaintingInfo paintInfo) {
RectanglePaintingInfo rectanglePaintInfo = (RectanglePaintingInfo)paintInfo;
int pageWidth = dataStream.getCurrentPage().getWidth();
int pageHeight = dataStream.getCurrentPage().getHeight();

AFPUnitConverter unitConv = paintingState.getUnitConverter();
float width = unitConv.pt2units(rectanglePaintInfo.getWidth());
float height = unitConv.pt2units(rectanglePaintInfo.getHeight());
float x = unitConv.pt2units(rectanglePaintInfo.getX());
float y = unitConv.pt2units(rectanglePaintInfo.getY());

AffineTransform at = paintingState.getData().getTransform();

AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
lineDataInfo.color = paintingState.getColor();
lineDataInfo.rotation = paintingState.getRotation();
lineDataInfo.thickness = Math.round(height);

switch (lineDataInfo.rotation) {
case 0:
lineDataInfo.x1 = Math.round((float)at.getTranslateX() + x);
lineDataInfo.y1 = lineDataInfo.y2 = Math.round((float)at.getTranslateY() + y);
lineDataInfo.x2 = Math.round((float)at.getTranslateX() + x + width);
break;
case 90:
lineDataInfo.x1 = Math.round((float)at.getTranslateY() + x);
lineDataInfo.y1 = lineDataInfo.y2
= pageWidth - Math.round((float)at.getTranslateX()) + Math.round(y);
lineDataInfo.x2 = Math.round(width + (float)at.getTranslateY() + x);
break;
case 180:
lineDataInfo.x1 = pageWidth - Math.round((float)at.getTranslateX() - x);
lineDataInfo.y1 = lineDataInfo.y2 = pageHeight - Math.round((float)at.getTranslateY() - y);
lineDataInfo.x2 = pageWidth - Math.round((float)at.getTranslateX() - x - width);
break;
case 270:
lineDataInfo.x1 = pageHeight - Math.round((float)at.getTranslateY() - x);
lineDataInfo.y1 = lineDataInfo.y2 = Math.round((float)at.getTranslateX() + y);
lineDataInfo.x2 = lineDataInfo.x1 + Math.round(width - x);
break;
}
dataStream.createLine(lineDataInfo);
}
}

+ 141
- 0
src/java/org/apache/fop/afp/AFPResourceInfo.java View File

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

/* $Id: $ */

package org.apache.fop.afp;


/**
* The level at which a resource is to reside in the AFP output
*/
public class AFPResourceInfo {
private static final AFPResourceLevel DEFAULT_LEVEL
= new AFPResourceLevel(AFPResourceLevel.PRINT_FILE);

/** the uri of this resource */
private String uri = null;

/** the reference name of this resource */
private String name = null;

/** the resource level of this resource */
private AFPResourceLevel level = DEFAULT_LEVEL;

/** true when the resource level was changed */
private boolean levelChanged = false;

/**
* Sets the data object uri
*
* @param uri the data object uri
*/
public void setUri(String uri) {
this.uri = uri;
}

/**
* Returns the uri of this data object
*
* @return the uri of this data object
*/
public String getUri() {
return uri;
}

/**
* Sets the resource reference name
*
* @param resourceName the resource reference name
*/
public void setName(String resourceName) {
this.name = resourceName;
}

/**
* Returns the resource reference name
*
* @return the resource reference name
*/
public String getName() {
return this.name;
}

/**
* Returns the resource level
*
* @return the resource level
*/
public AFPResourceLevel getLevel() {
if (level == null) {
return DEFAULT_LEVEL;
}
return this.level;
}

/**
* Sets the resource level
*
* @param resourceLevel the resource level
*/
public void setLevel(AFPResourceLevel resourceLevel) {
this.level = resourceLevel;
levelChanged = true;
}

/**
* Returns true when the resource level was set
*
* @return true when the resource level was set
*/
public boolean levelChanged() {
return levelChanged;
}

/** {@inheritDoc} */
public String toString() {
return "AFPResourceInfo{uri=" + uri
+ (name != null ? ", name=" + name : "")
+ (level != null ? ", level=" + level : "")
+ "}";

}

/** {@inheritDoc} */
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if ((obj == null) || !(obj instanceof AFPResourceInfo)) {
return false;
}

AFPResourceInfo ri = (AFPResourceInfo)obj;
return (uri == ri.uri || uri != null && uri.equals(ri.uri))
&& (name == ri.name || name != null && name.equals(ri.name))
&& (level == ri.level || level != null && level.equals(ri.level));
}

/** {@inheritDoc} */
public int hashCode() {
int hash = 7;
hash = 31 * hash + (null == uri ? 0 : uri.hashCode());
hash = 31 * hash + (null == name ? 0 : name.hashCode());
hash = 31 * hash + (null == level ? 0 : level.hashCode());
return hash;
}
}

+ 201
- 0
src/java/org/apache/fop/afp/AFPResourceLevel.java View File

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

/* $Id$ */

package org.apache.fop.afp;

/**
* A resource level
*/
public class AFPResourceLevel {

/** directly in page **/
public static final int INLINE = 0;

/** page level **/
public static final int PAGE = 1;

/** page group level **/
public static final int PAGE_GROUP = 2;

/** document level **/
public static final int DOCUMENT = 3;

/** print file level **/
public static final int PRINT_FILE = 4;

/** external level **/
public static final int EXTERNAL = 5;

private static final String NAME_INLINE = "inline";
private static final String NAME_PAGE = "page";
private static final String NAME_PAGE_GROUP = "page-group";
private static final String NAME_DOCUMENT = "document";
private static final String NAME_PRINT_FILE = "print-file";
private static final String NAME_EXTERNAL = "external";

private static final String[] NAMES = new String[] {
NAME_INLINE, NAME_PAGE, NAME_PAGE_GROUP, NAME_DOCUMENT, NAME_PRINT_FILE, NAME_EXTERNAL
};


/** where the resource will reside in the AFP output */
private int level = PRINT_FILE; // default is print-file level (images)

/** the external resource group file path */
private String extFilePath = null;

/**
* Sets the resource placement level within the AFP output
*
* @param levelString the resource level (page, page-group, document, print-file or external)
* @return true if the resource level was successfully set
*/
public static AFPResourceLevel valueOf(String levelString) {
if (levelString != null) {
levelString = levelString.toLowerCase();
AFPResourceLevel resourceLevel = null;
for (int i = 0; i < NAMES.length; i++) {
if (NAMES[i].equals(levelString)) {
resourceLevel = new AFPResourceLevel(i);
break;
}
}
return resourceLevel;
}
return null;
}

/**
* Main constructor
*
* @param level the resource level
*/
public AFPResourceLevel(int level) {
setLevel(level);
}

/**
* Sets the resource level
*
* @param level the resource level
*/
public void setLevel(int level) {
this.level = level;
}

/**
* Returns true if this is at page level
*
* @return true if this is at page level
*/
public boolean isPage() {
return level == PAGE;
}

/**
* Returns true if this is at page group level
*
* @return true if this is at page group level
*/
public boolean isPageGroup() {
return level == PAGE_GROUP;
}

/**
* Returns true if this is at document level
*
* @return true if this is at document level
*/
public boolean isDocument() {
return level == DOCUMENT;
}

/**
* Returns true if this is at external level
*
* @return true if this is at external level
*/
public boolean isExternal() {
return level == EXTERNAL;
}

/**
* Returns true if this is at print-file level
*
* @return true if this is at print-file level
*/
public boolean isPrintFile() {
return level == PRINT_FILE;
}

/**
* Returns true if this resource level is inline
*
* @return true if this resource level is inline
*/
public boolean isInline() {
return level == INLINE;
}

/**
* Returns the destination file path of the external resource group file
*
* @return the destination file path of the external resource group file
*/
public String getExternalFilePath() {
return this.extFilePath;
}

/**
* Sets the external destination of the resource
*
* @param filePath the external resource group file
*/
public void setExternalFilePath(String filePath) {
this.extFilePath = filePath;
}

/** {@inheritDoc} */
public String toString() {
return NAMES[level] + (isExternal() ? ", file=" + extFilePath : "");
}

/** {@inheritDoc} */
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if ((obj == null) || !(obj instanceof AFPResourceLevel)) {
return false;
}

AFPResourceLevel rl = (AFPResourceLevel)obj;
return (level == level)
&& (extFilePath == rl.extFilePath
|| extFilePath != null && extFilePath.equals(rl.extFilePath));
}

/** {@inheritDoc} */
public int hashCode() {
int hash = 7;
hash = 31 * hash + level;
hash = 31 * hash + (null == extFilePath ? 0 : extFilePath.hashCode());
return hash;
}
}

+ 179
- 0
src/java/org/apache/fop/afp/AFPResourceManager.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;

import org.apache.fop.afp.modca.AbstractNamedAFPObject;
import org.apache.fop.afp.modca.IncludeObject;
import org.apache.fop.afp.modca.Registry;
import org.apache.fop.afp.modca.ResourceGroup;

/**
* Manages the creation and storage of document resources
*/
public class AFPResourceManager {
/** The AFP datastream (document tree) */
private DataStream dataStream;

/** Resource creation factory */
private final Factory factory;

private final AFPStreamer streamer;

private final AFPDataObjectFactory dataObjectFactory;

/** Maintain a reference count of instream objects for referencing purposes */
private int instreamObjectCount = 0;

/** a mapping of resourceInfo --> include name */
private final Map/*<AFPResourceInfo,String>*/ includeNameMap
= new java.util.HashMap()/*<AFPResourceInfo,String>*/;

/**
* Main constructor
*/
public AFPResourceManager() {
this.factory = new Factory();
this.streamer = new AFPStreamer(factory);
this.dataObjectFactory = new AFPDataObjectFactory(factory);
}

/**
* Sets the outputstream
*
* @param paintingState the AFP painting state
* @param outputStream the outputstream
* @return a new AFP DataStream
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public DataStream createDataStream(AFPPaintingState paintingState, OutputStream outputStream)
throws IOException {
this.dataStream = streamer.createDataStream(paintingState);
streamer.setOutputStream(outputStream);
return this.dataStream;
}

/**
* Returns the AFP DataStream
*
* @return the AFP DataStream
*/
public DataStream getDataStream() {
return this.dataStream;
}

/**
* Tells the streamer to write
*
* @throws IOException thrown if an I/O exception of some sort has occurred.
*/
public void writeToStream() throws IOException {
streamer.close();
}

/**
* Sets the default resource group file path
*
* @param filePath the default resource group file path
*/

public void setDefaultResourceGroupFilePath(String filePath) {
streamer.setDefaultResourceGroupFilePath(filePath);
}

/**
* Creates a new data object in the AFP datastream
*
* @param dataObjectInfo the data object info
*
* @throws IOException thrown if an I/O exception of some sort has occurred.
*/
public void createObject(AFPDataObjectInfo dataObjectInfo) throws IOException {
AbstractNamedAFPObject namedObj = null;

AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
String uri = resourceInfo.getUri();
if (uri == null) {
uri = "/";
}
// if this is an instream data object adjust the uri to ensure that its unique
if (uri.endsWith("/")) {
uri += "#" + (++instreamObjectCount);
resourceInfo.setUri(uri);
}

String objectName = (String)includeNameMap.get(resourceInfo);
if (objectName == null) {
boolean useInclude = true;
Registry.ObjectType objectType = null;

// new resource so create
if (dataObjectInfo instanceof AFPImageObjectInfo) {
AFPImageObjectInfo imageObjectInfo = (AFPImageObjectInfo)dataObjectInfo;
namedObj = dataObjectFactory.createImage(imageObjectInfo);
} else if (dataObjectInfo instanceof AFPGraphicsObjectInfo) {
AFPGraphicsObjectInfo graphicsObjectInfo = (AFPGraphicsObjectInfo)dataObjectInfo;
namedObj = dataObjectFactory.createGraphic(graphicsObjectInfo);
} else {
// natively embedded data object
namedObj = dataObjectFactory.createObjectContainer(dataObjectInfo);
objectType = dataObjectInfo.getObjectType();
useInclude = objectType != null && objectType.isIncludable();
}

AFPResourceLevel resourceLevel = resourceInfo.getLevel();
ResourceGroup resourceGroup = streamer.getResourceGroup(resourceLevel);
useInclude &= resourceGroup != null;
if (useInclude) {
// if it is to reside within a resource group at print-file or external level
if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) {
// wrap newly created data object in a resource object
namedObj = dataObjectFactory.createResource(namedObj, resourceInfo, objectType);
}

// add data object into its resource group destination
resourceGroup.addObject(namedObj);

// create the include object
objectName = namedObj.getName();
IncludeObject includeObject
= dataObjectFactory.createInclude(objectName, dataObjectInfo);

// add an include to the current page
dataStream.getCurrentPage().addObject(includeObject);

// record mapping of resource info to data object resource name
includeNameMap.put(resourceInfo, objectName);
} else {
// not to be included so inline data object directly into the current page
dataStream.getCurrentPage().addObject(namedObj);
}
} else {
// an existing data resource so reference it by adding an include to the current page
IncludeObject includeObject
= dataObjectFactory.createInclude(objectName, dataObjectInfo);
dataStream.getCurrentPage().addObject(includeObject);
}
}

}

+ 215
- 0
src/java/org/apache/fop/afp/AFPStreamer.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.StreamedResourceGroup;

/**
* Manages the streaming of the AFP output
*/
public class AFPStreamer implements Streamable {
/** Static logging instance */
private static final Log log = LogFactory.getLog(AFPStreamer.class);

private static final String AFPDATASTREAM_TEMP_FILE_PREFIX = "AFPDataStream_";

private static final int BUFFER_SIZE = 4096; // 4k writing buffer

private static final String DEFAULT_EXTERNAL_RESOURCE_FILENAME = "resources.afp";


private final Factory factory;

/** A mapping of external resource destinations to resource groups */
private final Map/*<String,AFPExternalResourceGroup>*/pathResourceGroupMap
= new java.util.HashMap/*<String,AFPExternalResourceGroup>*/();

private StreamedResourceGroup printFileResourceGroup;

/** Sets the default resource group file path */
private String defaultResourceGroupFilePath = DEFAULT_EXTERNAL_RESOURCE_FILENAME;

private File tempFile;

/** temporary document outputstream */
private OutputStream documentOutputStream;

/** the final outputstream */
private OutputStream outputStream;

private RandomAccessFile documentFile;

private DataStream dataStream;

/**
* Main constructor
*
* @param factory a factory
*/
public AFPStreamer(Factory factory) {
this.factory = factory;
}

/**
* Creates a new DataStream
*
* @param paintingState the AFP painting state
* @return a new {@link DataStream}
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public DataStream createDataStream(AFPPaintingState paintingState) throws IOException {
this.tempFile = File.createTempFile(AFPDATASTREAM_TEMP_FILE_PREFIX, null);
this.documentFile = new RandomAccessFile(tempFile, "rw");
this.documentOutputStream = new BufferedOutputStream(
new FileOutputStream(documentFile.getFD()));
this.dataStream = factory.createDataStream(paintingState, documentOutputStream);
return dataStream;
}

/**
* Sets the default resource group file path
*
* @param filePath the default resource group file path
*/
public void setDefaultResourceGroupFilePath(String filePath) {
this.defaultResourceGroupFilePath = filePath;
}

/**
* Returns the resource group for a given resource info
*
* @param level a resource level
* @return a resource group for the given resource info
*/
public ResourceGroup getResourceGroup(AFPResourceLevel level) {
ResourceGroup resourceGroup = null;
if (level.isInline()) { // no resource group for inline level
return null;
}
if (level.isExternal()) {
String filePath = level.getExternalFilePath();
if (filePath == null) {
log.warn("No file path provided for external resource, using default.");
filePath = defaultResourceGroupFilePath;
}
resourceGroup = (ResourceGroup)pathResourceGroupMap.get(filePath);
if (resourceGroup == null) {
OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(filePath));
} catch (FileNotFoundException fnfe) {
log.error("Failed to create/open external resource group file '"
+ filePath + "'");
} finally {
if (os != null) {
resourceGroup = factory.createStreamedResourceGroup(os);
pathResourceGroupMap.put(filePath, resourceGroup);
}
}
}
} else if (level.isPrintFile()) {
if (printFileResourceGroup == null) {
// use final outputstream for print-file resource group
printFileResourceGroup = factory.createStreamedResourceGroup(outputStream);
}
resourceGroup = printFileResourceGroup;
} else {
// resource group in afp document datastream
resourceGroup = dataStream.getResourceGroup(level);
}
return resourceGroup;
}

/**
* Closes off the AFP stream writing the document stream
*
* @throws IOException if an an I/O exception of some sort has occurred
*/
// write out any external resource groups
public void close() throws IOException {
Iterator it = pathResourceGroupMap.entrySet().iterator();
while (it.hasNext()) {
StreamedResourceGroup resourceGroup = (StreamedResourceGroup)it.next();
resourceGroup.close();
}

// close any open print-file resource group
if (printFileResourceGroup != null) {
printFileResourceGroup.close();
}

// write out document
writeToStream(outputStream);

outputStream.close();

// delete temporary file
tempFile.delete();
}

/**
* Sets the final outputstream
*
* @param outputStream an outputstream
*/
public void setOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
// long start = System.currentTimeMillis();
int len = (int)documentFile.length();
int numChunks = len / BUFFER_SIZE;
int remainingChunkSize = len % BUFFER_SIZE;
byte[] buffer;

documentFile.seek(0);
if (numChunks > 0) {
buffer = new byte[BUFFER_SIZE];
for (int i = 0; i < numChunks; i++) {
documentFile.read(buffer, 0, BUFFER_SIZE);
os.write(buffer, 0, BUFFER_SIZE);
}
} else {
buffer = new byte[remainingChunkSize];
}
if (remainingChunkSize > 0) {
documentFile.read(buffer, 0, remainingChunkSize);
os.write(buffer, 0, remainingChunkSize);
}
os.flush();
// long end = System.currentTimeMillis();
// log.debug("writing time " + (end - start) + "ms");
}
}

+ 232
- 0
src/java/org/apache/fop/afp/AFPTextDataInfo.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.awt.Color;

/**
* Text data information
*/
public class AFPTextDataInfo {

/** the text font reference */
private int fontReference;

/** the text x coordinate position */
private int x;

/** the text y coordinate position */
private int y;

/** the text color */
private Color color;

/** the text variable space adjustment */
private int variableSpaceCharacterIncrement;

/** the text inter character adjustment */
private int interCharacterAdjustment;

/** the text orientation */
private int rotation;

/** the text encoding */
private String textEncoding;

/** the text string */
private String textString;

/**
* Returns the font reference
*
* @return the font reference
*/
public int getFontReference() {
return fontReference;
}

/**
* Sets the font reference
*
* @param fontReference the font reference
*/
public void setFontReference(int fontReference) {
this.fontReference = fontReference;
}

/**
* Returns the x coordinate
*
* @return the x coordinate
*/
public int getX() {
return x;
}

/**
* Sets the X coordinate
*
* @param x the X coordinate
*/
public void setX(int x) {
this.x = x;
}

/**
* Returns the y coordinate
*
* @return the y coordinate
*/
public int getY() {
return y;
}

/**
* Sets the Y coordinate
*
* @param y the Y coordinate
*/
public void setY(int y) {
this.y = y;
}

/**
* Returns the color
*
* @return the color
*/
public Color getColor() {
return color;
}

/**
* Sets the color
*
* @param color the color
*/
public void setColor(Color color) {
this.color = color;
}

/**
* Return the variable space character increment
*
* @return the variable space character increment
*/
public int getVariableSpaceCharacterIncrement() {
return variableSpaceCharacterIncrement;
}

/**
* Sets the variable space character increment
*
* @param variableSpaceCharacterIncrement the variable space character increment
*/
public void setVariableSpaceCharacterIncrement(
int variableSpaceCharacterIncrement) {
this.variableSpaceCharacterIncrement = variableSpaceCharacterIncrement;
}

/**
* Return the inter character adjustment
*
* @return the inter character adjustment
*/
public int getInterCharacterAdjustment() {
return interCharacterAdjustment;
}

/**
* Sets the inter character adjustment
*
* @param interCharacterAdjustment the inter character adjustment
*/
public void setInterCharacterAdjustment(int interCharacterAdjustment) {
this.interCharacterAdjustment = interCharacterAdjustment;
}

/**
* Sets the text orientation
*
* @param rotation the text rotation
*/
public void setRotation(int rotation) {
this.rotation = rotation;
}

/**
* Returns the text rotation
*
* @return the text rotation
*/
public int getRotation() {
return this.rotation;
}

/**
* Sets the text encoding
*
* @param textEncoding the text encoding
*/
public void setEncoding(String textEncoding) {
this.textEncoding = textEncoding;
}

/**
* Returns the text encoding
*
* @return the text encoding
*/
public String getEncoding() {
return this.textEncoding;
}

/**
* Sets the text string
*
* @param textString the text string
*/
public void setString(String textString) {
this.textString = textString;
}

/**
* Returns the text string
*
* @return the text string
*/
public String getString() {
return this.textString;
}

/** {@inheritDoc} */
public String toString() {
return "TextDataInfo{fontReference=" + fontReference
+ ", x=" + x
+ ", y=" + y
+ ", color=" + color
+ ", vsci=" + variableSpaceCharacterIncrement
+ ", ica=" + interCharacterAdjustment
+ ", orientation=" + rotation
+ ", textString=" + textString
+ ", textEncoding=" + textEncoding
+ "}";
}
}

+ 121
- 0
src/java/org/apache/fop/afp/AFPUnitConverter.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.awt.geom.AffineTransform;



/**
* AFP Unit converter
*/
public class AFPUnitConverter {

/** the AFP state */
private final AFPPaintingState paintingState;

/**
* Unit converter
*
* @param paintingState the AFP painting state
*/
public AFPUnitConverter(AFPPaintingState paintingState) {
this.paintingState = paintingState;
}

/**
* Converts millipoints to units
*
* @param srcPts source points
* @param dstPts destination points
* @return transformed points
*/
public int[] mpts2units(float[] srcPts, float[] dstPts) {
return transformPoints(srcPts, dstPts, true);
}

/**
* Converts points to units
*
* @param srcPts source points
* @param dstPts destination points
* @return transformed points
*/
public int[] pts2units(float[] srcPts, float[] dstPts) {
return transformPoints(srcPts, dstPts, false);
}

/**
* Converts millipoints to units
*
* @param srcPts source points
* @return transformed points
*/
public int[] mpts2units(float[] srcPts) {
return transformPoints(srcPts, null, true);
}

/**
* Converts points to units
*
* @param srcPts source points
* @return transformed points
*/
public int[] pts2units(float[] srcPts) {
return transformPoints(srcPts, null, false);
}

/**
* Converts point to unit
*
* @param pt point
* @return transformed point
*/
public float pt2units(float pt) {
return pt / ((float)AFPConstants.DPI_72 / paintingState.getResolution());
}

/**
* Converts millipoint to unit
*
* @param mpt millipoint
* @return transformed point
*/
public float mpt2units(float mpt) {
return mpt / ((float)AFPConstants.DPI_72_MPTS / paintingState.getResolution());
}

private int[] transformPoints(float[] srcPts, float[] dstPts, boolean milli) {
if (dstPts == null) {
dstPts = new float[srcPts.length];
}
AffineTransform at = paintingState.getData().getTransform();
at.transform(srcPts, 0, dstPts, 0, srcPts.length / 2);
int[] coords = new int[srcPts.length];
for (int i = 0; i < srcPts.length; i++) {
if (!milli) {
dstPts[i] *= 1000;
}
coords[i] = Math.round(dstPts[i]);
}
return coords;
}

}

+ 53
- 0
src/java/org/apache/fop/afp/AbstractAFPPainter.java View File

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

/* $Id$ */

package org.apache.fop.afp;

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

/**
* A base AFP painter
*/
public abstract class AbstractAFPPainter {

/** Static logging instance */
protected static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");

protected final DataStream dataStream;
protected final AFPPaintingState paintingState;

/**
* Main constructor
*
* @param paintingState the AFP painting state
* @param dataStream the AFP Datastream
*/
public AbstractAFPPainter(AFPPaintingState paintingState, DataStream dataStream) {
this.paintingState = paintingState;
this.dataStream = dataStream;
}

/**
* Paints the painting item
*
* @param paintInfo the painting information
*/
public abstract void paint(PaintingInfo paintInfo);
}

+ 121
- 0
src/java/org/apache/fop/afp/BorderPaintingInfo.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.awt.Color;

/**
* Border painting information
*/
public class BorderPaintingInfo implements PaintingInfo {

private final float x1;
private final float y1;
private final float x2;
private final float y2;
private final boolean isHorizontal;
private final int style;
private final Color color;

/**
* Main constructor
*
* @param x1 the x1 coordinate
* @param y1 the y1 coordinate
* @param x2 the x2 coordinate
* @param y2 the y2 coordinate
* @param isHorizontal true when the border line is horizontal
* @param style the border style
* @param color the border color
*/
public BorderPaintingInfo(float x1, float y1, float x2, float y2,
boolean isHorizontal, int style, Color color) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.isHorizontal = isHorizontal;
this.style = style;
this.color = color;
}

/**
* Returns the x1 coordinate
*
* @return the x1 coordinate
*/
public float getX1() {
return x1;
}

/**
* Returns the y1 coordinate
*
* @return the y1 coordinate
*/
public float getY1() {
return y1;
}

/**
* Returns the x2 coordinate
*
* @return the x2 coordinate
*/
public float getX2() {
return x2;
}

/**
* Returns the y2 coordinate
*
* @return the y2 coordinate
*/
public float getY2() {
return y2;
}

/**
* Returns true when this is a horizontal line
*
* @return true when this is a horizontal line
*/
public boolean isHorizontal() {
return isHorizontal;
}

/**
* Returns the style
*
* @return the style
*/
public int getStyle() {
return style;
}

/**
* Returns the color
*
* @return the color
*/
public Color getColor() {
return color;
}
}

+ 40
- 0
src/java/org/apache/fop/afp/Completable.java View File

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

/* $Id$ */

package org.apache.fop.afp;

/**
* Set and expose the internal completeness of an object.
*/
public interface Completable {

/**
* Sets whether or not this object is complete or not
*
* @param complete true if this object is complete
*/
void setComplete(boolean complete);

/**
* Returns true if this object is complete
*
* @return true if this object is complete
*/
boolean isComplete();
}

+ 602
- 0
src/java/org/apache/fop/afp/DataStream.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.awt.Color;
import java.awt.Point;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.fonts.AFPFontAttributes;
import org.apache.fop.afp.modca.AbstractPageObject;
import org.apache.fop.afp.modca.Document;
import org.apache.fop.afp.modca.InterchangeSet;
import org.apache.fop.afp.modca.Overlay;
import org.apache.fop.afp.modca.PageGroup;
import org.apache.fop.afp.modca.PageObject;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.TagLogicalElementBean;
import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;

/**
* A data stream is a continuous ordered stream of data elements and objects
* conforming to a given format. Application programs can generate data streams
* destined for a presentation service, archive library, presentation device or
* another application program. The strategic presentation data stream
* architectures used is Mixed Object Document Content Architecture (MO:DCA).
*
* The MO:DCA architecture defines the data stream used by applications to
* describe documents and object envelopes for interchange with other
* applications and application services. Documents defined in the MO:DCA format
* may be archived in a database, then later retrieved, viewed, annotated and
* printed in local or distributed systems environments. Presentation fidelity
* is accommodated by including resource objects in the documents that reference
* them.
*/
public class DataStream {

/** Static logging instance */
protected static final Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");

/** Boolean completion indicator */
private boolean complete = false;

/** The AFP document object */
private Document document = null;

/** The current page group object */
private PageGroup currentPageGroup = null;

/** The current page object */
private PageObject currentPageObject = null;

/** The current overlay object */
private Overlay currentOverlay = null;

/** The current page */
private AbstractPageObject currentPage = null;

/** The MO:DCA interchange set in use (default to MO:DCA-P IS/2 set) */
private InterchangeSet interchangeSet
= InterchangeSet.valueOf(InterchangeSet.MODCA_PRESENTATION_INTERCHANGE_SET_2);

private final Factory factory;

private OutputStream outputStream;

/** the afp painting state */
private final AFPPaintingState paintingState;

/**
* Default constructor for the AFPDocumentStream.
*
* @param factory the resource factory
* @param paintingState the AFP painting state
* @param outputStream the outputstream to write to
*/
public DataStream(Factory factory, AFPPaintingState paintingState, OutputStream outputStream) {
this.paintingState = paintingState;
this.factory = factory;
this.outputStream = outputStream;
}

/**
* Returns the outputstream
*
* @return the outputstream
*/
public OutputStream getOutputStream() {
return this.outputStream;
}

/**
* Returns the document object
*
* @return the document object
*/
private Document getDocument() {
return this.document;
}

/**
* Returns the current page
*
* @return the current page
*/
public AbstractPageObject getCurrentPage() {
return this.currentPage;
}

/**
* The document is started by invoking this method which creates an instance
* of the AFP Document object.
*
* @param name
* the name of this document.
*/
public void setDocumentName(String name) {
if (name != null) {
getDocument().setFullyQualifiedName(
FullyQualifiedNameTriplet.TYPE_BEGIN_DOCUMENT_REF,
FullyQualifiedNameTriplet.FORMAT_CHARSTR, name);
}
}

/**
* Helper method to mark the end of the current document.
*
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public void endDocument() throws IOException {
if (complete) {
String msg = "Invalid state - document already ended.";
log.warn("endDocument():: " + msg);
throw new IllegalStateException(msg);
}

if (currentPageObject != null) {
// End the current page if necessary
endPage();
}

if (currentPageGroup != null) {
// End the current page group if necessary
endPageGroup();
}

// Write out document
if (document != null) {
document.endDocument();
document.writeToStream(this.outputStream);
}

this.outputStream.flush();

this.complete = true;

this.document = null;

this.outputStream = null;
}

/**
* Start a new page. When processing has finished on the current page, the
* {@link #endPage()}method must be invoked to mark the page ending.
*
* @param pageWidth
* the width of the page
* @param pageHeight
* the height of the page
* @param pageRotation
* the rotation of the page
* @param pageWidthRes
* the width resolution of the page
* @param pageHeightRes
* the height resolution of the page
*/
public void startPage(int pageWidth, int pageHeight, int pageRotation,
int pageWidthRes, int pageHeightRes) {
currentPageObject = factory.createPage(pageWidth, pageHeight,
pageRotation, pageWidthRes, pageHeightRes);
currentPage = currentPageObject;
currentOverlay = null;
}

/**
* Start a new overlay. When processing has finished on the current overlay,
* the {@link #endOverlay()}method must be invoked to mark the overlay
* ending.
*
* @param x
* the x position of the overlay on the page
* @param y
* the y position of the overlay on the page
* @param width
* the width of the overlay
* @param height
* the height of the overlay
* @param widthRes
* the width resolution of the overlay
* @param heightRes
* the height resolution of the overlay
* @param overlayRotation
* the rotation of the overlay
*/
public void startOverlay(int x, int y, int width, int height, int widthRes,
int heightRes, int overlayRotation) {
this.currentOverlay = factory.createOverlay(
width, height, widthRes, heightRes, overlayRotation);

String overlayName = currentOverlay.getName();
currentPageObject.createIncludePageOverlay(overlayName, x, y, 0);
currentPage = currentOverlay;
}

/**
* Helper method to mark the end of the current overlay.
*
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public void endOverlay() throws IOException {
if (currentOverlay != null) {
currentOverlay.endPage();
currentOverlay = null;
currentPage = currentPageObject;
}
}

/**
* Helper method to save the current page.
*
* @return current page object that was saved
*/
public PageObject savePage() {
PageObject pageObject = currentPageObject;
if (currentPageGroup != null) {
currentPageGroup.addPage(currentPageObject);
} else {
document.addPage(currentPageObject);
}
currentPageObject = null;
currentPage = null;
return pageObject;
}

/**
* Helper method to restore the current page.
*
* @param pageObject
* page object
*/
public void restorePage(PageObject pageObject) {
currentPageObject = pageObject;
currentPage = pageObject;
}

/**
* Helper method to mark the end of the current page.
*
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public void endPage() throws IOException {
if (currentPageObject != null) {
currentPageObject.endPage();
if (currentPageGroup != null) {
currentPageGroup.addPage(currentPageObject);
currentPageGroup.writeToStream(this.outputStream);
} else {
document.addPage(currentPageObject);
document.writeToStream(this.outputStream);
}
currentPageObject = null;
currentPage = null;
}
}

/**
* Creates the given page fonts in the current page
*
* @param pageFonts
* a collection of AFP font attributes
*/
public void addFontsToCurrentPage(Map pageFonts) {
Iterator iter = pageFonts.values().iterator();
while (iter.hasNext()) {
AFPFontAttributes afpFontAttributes = (AFPFontAttributes) iter
.next();
createFont(afpFontAttributes.getFontReference(), afpFontAttributes
.getFont(), afpFontAttributes.getPointSize());
}
}

/**
* Helper method to create a map coded font object on the current page, this
* method delegates the construction of the map coded font object to the
* active environment group on the current page.
*
* @param fontReference
* the font number used as the resource identifier
* @param font
* the font
* @param size
* the point size of the font
*/
public void createFont(int fontReference, AFPFont font, int size) {
currentPage.createFont(fontReference, font, size);
}

/**
* Returns a point on the current page
*
* @param x the X-coordinate
* @param y the Y-coordinate
* @return a point on the current page
*/
private Point getPoint(int x, int y) {
Point p = new Point();
int rotation = paintingState.getRotation();
switch (rotation) {
case 90:
p.x = y;
p.y = currentPage.getWidth() - x;
break;
case 180:
p.x = currentPage.getWidth() - x;
p.y = currentPage.getHeight() - y;
break;
case 270:
p.x = currentPage.getHeight() - y;
p.y = x;
break;
default:
p.x = x;
p.y = y;
break;
}
return p;
}

/**
* Helper method to create text on the current page, this method delegates
* to the current presentation text object in order to construct the text.
*
* @param textDataInfo
* the afp text data
* @throws UnsupportedEncodingException thrown if character encoding is not supported
*/
public void createText(AFPTextDataInfo textDataInfo) throws UnsupportedEncodingException {
int rotation = paintingState.getRotation();
if (rotation != 0) {
textDataInfo.setRotation(rotation);
Point p = getPoint(textDataInfo.getX(), textDataInfo.getY());
textDataInfo.setX(p.x);
textDataInfo.setY(p.y);
}
currentPage.createText(textDataInfo);
}

/**
* Method to create a line on the current page.
*
* @param lineDataInfo the line data information.
*/
public void createLine(AFPLineDataInfo lineDataInfo) {
currentPage.createLine(lineDataInfo);
}

/**
* This method will create shading on the page using the specified
* coordinates (the shading contrast is controlled via the red, green, blue
* parameters, by converting this to grey scale).
*
* @param x
* the x coordinate of the shading
* @param y
* the y coordinate of the shading
* @param w
* the width of the shaded area
* @param h
* the height of the shaded area
* @param col
* the shading color
*/
public void createShading(int x, int y, int w, int h, Color col) {
currentPageObject.createShading(x, y, w, h, col.getRed(), col.getGreen(), col.getBlue());
}

/**
* Helper method which allows creation of the MPO object, via the AEG. And
* the IPO via the Page. (See actual object for descriptions.)
*
* @param name
* the name of the static overlay
*/
public void createIncludePageOverlay(String name) {
currentPageObject.createIncludePageOverlay(name, 0, 0, paintingState.getRotation());
currentPageObject.getActiveEnvironmentGroup().createOverlay(name);
}

/**
* Helper method which allows creation of the IMM object.
*
* @param name
* the name of the medium map
*/
public void createInvokeMediumMap(String name) {
currentPageGroup.createInvokeMediumMap(name);
}

/**
* Creates an IncludePageSegment on the current page.
*
* @param name
* the name of the include page segment
* @param x
* the x coordinate for the overlay
* @param y
* the y coordinate for the overlay
*/
public void createIncludePageSegment(String name, int x, int y) {
int xOrigin;
int yOrigin;
int orientation = paintingState.getRotation();
switch (orientation) {
case 90:
xOrigin = currentPage.getWidth() - y;
yOrigin = x;
break;
case 180:
xOrigin = currentPage.getWidth() - x;
yOrigin = currentPage.getHeight() - y;
break;
case 270:
xOrigin = y;
yOrigin = currentPage.getHeight() - x;
break;
default:
xOrigin = x;
yOrigin = y;
break;
}
currentPage.createIncludePageSegment(name, xOrigin, yOrigin);
}

/**
* Creates a TagLogicalElement on the current page.
*
* @param attributes
* the array of key value pairs.
*/
public void createPageTagLogicalElement(TagLogicalElementBean[] attributes) {
for (int i = 0; i < attributes.length; i++) {
String name = attributes[i].getKey();
String value = attributes[i].getValue();
currentPage.createTagLogicalElement(name, value);
}
}

/**
* Creates a TagLogicalElement on the current page group.
*
* @param attributes
* the array of key value pairs.
*/
public void createPageGroupTagLogicalElement(TagLogicalElementBean[] attributes) {
for (int i = 0; i < attributes.length; i++) {
String name = attributes[i].getKey();
String value = attributes[i].getValue();
currentPageGroup.createTagLogicalElement(name, value);
}
}

/**
* Creates a TagLogicalElement on the current page or page group
*
* @param name
* The tag name
* @param value
* The tag value
*/
public void createTagLogicalElement(String name, String value) {
if (currentPageGroup != null) {
currentPageGroup.createTagLogicalElement(name, value);
} else {
currentPage.createTagLogicalElement(name, value);
}
}

/**
* Creates a NoOperation item
*
* @param content
* byte data
*/
public void createNoOperation(String content) {
currentPage.createNoOperation(content);
}

/**
* Returns the current page group
*
* @return the current page group
*/
public PageGroup getCurrentPageGroup() {
return this.currentPageGroup;
}

/**
* Start a new document.
*
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public void startDocument() throws IOException {
this.document = factory.createDocument();
document.writeToStream(this.outputStream);
}

/**
* Start a new page group. When processing has finished on the current page
* group the {@link #endPageGroup()}method must be invoked to mark the page
* group ending.
*
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public void startPageGroup() throws IOException {
endPageGroup();
this.currentPageGroup = factory.createPageGroup();
}

/**
* Helper method to mark the end of the page group.
*
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public void endPageGroup() throws IOException {
if (currentPageGroup != null) {
currentPageGroup.endPageGroup();
document.addPageGroup(currentPageGroup);
document.writeToStream(outputStream);
currentPageGroup = null;
}
}

/**
* Sets the MO:DCA interchange set to use
*
* @param interchangeSet the MO:DCA interchange set
*/
public void setInterchangeSet(InterchangeSet interchangeSet) {
this.interchangeSet = interchangeSet;
}

/**
* Returns the MO:DCA interchange set in use
*
* @return the MO:DCA interchange set in use
*/
public InterchangeSet getInterchangeSet() {
return this.interchangeSet;
}

/**
* Returns the resource group for a given resource info
*
* @param level a resource level
* @return a resource group for the given resource info
*/
public ResourceGroup getResourceGroup(AFPResourceLevel level) {
ResourceGroup resourceGroup = null;
if (level.isDocument()) {
resourceGroup = document.getResourceGroup();
} else if (level.isPageGroup()) {
resourceGroup = currentPageGroup.getResourceGroup();
} else if (level.isPage()) {
resourceGroup = currentPageObject.getResourceGroup();
}
return resourceGroup;
}

}

+ 635
- 0
src/java/org/apache/fop/afp/Factory.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.io.OutputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.goca.GraphicsData;
import org.apache.fop.afp.ioca.ImageContent;
import org.apache.fop.afp.ioca.ImageRasterData;
import org.apache.fop.afp.ioca.ImageSegment;
import org.apache.fop.afp.ioca.ImageSizeParameter;
import org.apache.fop.afp.modca.ActiveEnvironmentGroup;
import org.apache.fop.afp.modca.ContainerDataDescriptor;
import org.apache.fop.afp.modca.Document;
import org.apache.fop.afp.modca.GraphicsDataDescriptor;
import org.apache.fop.afp.modca.GraphicsObject;
import org.apache.fop.afp.modca.IMImageObject;
import org.apache.fop.afp.modca.ImageDataDescriptor;
import org.apache.fop.afp.modca.ImageObject;
import org.apache.fop.afp.modca.IncludeObject;
import org.apache.fop.afp.modca.IncludePageSegment;
import org.apache.fop.afp.modca.InvokeMediumMap;
import org.apache.fop.afp.modca.MapCodedFont;
import org.apache.fop.afp.modca.MapContainerData;
import org.apache.fop.afp.modca.MapDataResource;
import org.apache.fop.afp.modca.ObjectAreaDescriptor;
import org.apache.fop.afp.modca.ObjectAreaPosition;
import org.apache.fop.afp.modca.ObjectContainer;
import org.apache.fop.afp.modca.ObjectEnvironmentGroup;
import org.apache.fop.afp.modca.Overlay;
import org.apache.fop.afp.modca.PageDescriptor;
import org.apache.fop.afp.modca.PageGroup;
import org.apache.fop.afp.modca.PageObject;
import org.apache.fop.afp.modca.PresentationEnvironmentControl;
import org.apache.fop.afp.modca.PresentationTextDescriptor;
import org.apache.fop.afp.modca.PresentationTextObject;
import org.apache.fop.afp.modca.ResourceEnvironmentGroup;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.ResourceObject;
import org.apache.fop.afp.modca.StreamedResourceGroup;
import org.apache.fop.afp.modca.TagLogicalElement;
import org.apache.fop.afp.util.StringUtils;

/**
* Creator of MO:DCA structured field objects
*/
public class Factory {

/** Static logging instance */
private static final Log log = LogFactory.getLog(Factory.class);

private static final String OBJECT_ENVIRONMENT_GROUP_NAME_PREFIX = "OEG";

private static final String ACTIVE_ENVIRONMENT_GROUP_NAME_PREFIX = "AEG";

private static final String IMAGE_NAME_PREFIX = "IMG";

private static final String GRAPHIC_NAME_PREFIX = "GRA";

private static final String BARCODE_NAME_PREFIX = "BAR";

// private static final String OTHER_NAME_PREFIX = "OTH";

private static final String OBJECT_CONTAINER_NAME_PREFIX = "OC";

private static final String RESOURCE_NAME_PREFIX = "RES";

private static final String RESOURCE_GROUP_NAME_PREFIX = "RG";

private static final String PAGE_GROUP_NAME_PREFIX = "PGP";

private static final String PAGE_NAME_PREFIX = "PGN";

private static final String OVERLAY_NAME_PREFIX = "OVL";

private static final String PRESENTATION_TEXT_NAME_PREFIX = "PT";

private static final String DOCUMENT_NAME_PREFIX = "DOC";

private static final String IM_IMAGE_NAME_PREFIX = "IMIMG";

private static final String IMAGE_SEGMENT_NAME_PREFIX = "IS";


/** the page group count */
private int pageGroupCount = 0;

/** the page count */
private int pageCount = 0;

/** the image count */
private int imageCount = 0;

/** the im image count */
private int imImageCount = 0;

/** the image segment count */
private int imageSegmentCount = 0;

/** the graphic count */
private int graphicCount = 0;

/** the object container count */
private int objectContainerCount = 0;

/** the resource count */
private int resourceCount = 0;

/** the resource group count */
private int resourceGroupCount = 0;

/** the overlay count */
private int overlayCount = 0;

/** the presentation text object count */
private int textObjectCount = 0;

/** the active environment group count */
private int activeEnvironmentGroupCount = 0;

/** the document count */
private int documentCount = 0;

/** the object environment group count */
private int objectEnvironmentGroupCount = 0;

/**
* Main constructor
*/
public Factory() {
}

/**
* Creates a new IOCA {@link ImageObject}
*
* @return a new {@link ImageObject}
*/
public ImageObject createImageObject() {
String name = IMAGE_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++imageCount), '0', 5);
ImageObject imageObject = new ImageObject(this, name);
return imageObject;
}

/**
* Creates an IOCA {@link IMImageObject}
*
* @return a new {@link IMImageObject}
*/
public IMImageObject createIMImageObject() {
String name = IM_IMAGE_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++imImageCount), '0', 3);
IMImageObject imImageObject = new IMImageObject(name);
return imImageObject;
}

/**
* Creates a new GOCA {@link GraphicsObject}
*
* @return a new {@link GraphicsObject}
*/
public GraphicsObject createGraphicsObject() {
String name = GRAPHIC_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++graphicCount), '0', 5);
GraphicsObject graphicsObj = new GraphicsObject(this, name);
return graphicsObj;
}

/**
* Creates a new MO:DCA {@link ObjectContainer}
*
* @return a new {@link ObjectContainer}
*/
public ObjectContainer createObjectContainer() {
String name = OBJECT_CONTAINER_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++objectContainerCount), '0', 6);
return new ObjectContainer(this, name);
}

/**
* Creates a new MO:DCA {@link ResourceObject}
*
* @param resourceName the resource object name
* @return a new {@link ResourceObject}
*/
public ResourceObject createResource(String resourceName) {
return new ResourceObject(resourceName);
}

/**
* Creates a new MO:DCA {@link ResourceObject}
*
* @return a new {@link ResourceObject}
*/
public ResourceObject createResource() {
String name = RESOURCE_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++resourceCount), '0', 5);
return createResource(name);
}

/**
* Creates a new MO:DCA {@link PageGroup}
*
* @return a new {@link PageGroup}
*/
public PageGroup createPageGroup() {
String name = PAGE_GROUP_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++pageGroupCount), '0', 5);
return new PageGroup(this, name);
}

/**
* Creates a new MO:DCA {@link ActiveEnvironmentGroup}
*
* @param width the page width
* @param height the page height
* @param widthRes the page width resolution
* @param heightRes the page height resolution
* @return a new {@link ActiveEnvironmentGroup}
*/
public ActiveEnvironmentGroup createActiveEnvironmentGroup(
int width, int height, int widthRes, int heightRes) {
String name = ACTIVE_ENVIRONMENT_GROUP_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++activeEnvironmentGroupCount ), '0', 5);
return new ActiveEnvironmentGroup(this, name, width, height, widthRes, heightRes);
}

/**
* Creates a new MO:DCA {@link ResourceGroup}
*
* @return a new {@link ResourceGroup}
*/
public ResourceGroup createResourceGroup() {
String name = RESOURCE_GROUP_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++resourceGroupCount), '0', 6);
return new ResourceGroup(name);
}

/**
* Creates a new MO:DCA {@link StreamedResourceGroup}
*
* @param os the outputstream of the streamed resource group
* @return a new {@link StreamedResourceGroup}
*/
public StreamedResourceGroup createStreamedResourceGroup(OutputStream os) {
String name = RESOURCE_GROUP_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++resourceGroupCount), '0', 6);
return new StreamedResourceGroup(name, os);
}

/**
* Creates a new MO:DCA {@link PageObject}.
*
* @param pageWidth
* the width of the page
* @param pageHeight
* the height of the page
* @param pageRotation
* the rotation of the page
* @param pageWidthRes
* the width resolution of the page
* @param pageHeightRes
* the height resolution of the page
*
* @return a new {@link PageObject}
*/
public PageObject createPage(int pageWidth, int pageHeight, int pageRotation,
int pageWidthRes, int pageHeightRes) {
String pageName = PAGE_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++pageCount), '0', 5);
return new PageObject(this, pageName, pageWidth, pageHeight,
pageRotation, pageWidthRes, pageHeightRes);
}


/**
* Creates a new MO:DCA {@link PresentationTextObject}.
*
* @return a new {@link PresentationTextObject}
*/
public PresentationTextObject createPresentationTextObject() {
String textObjectName = PRESENTATION_TEXT_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++textObjectCount), '0', 6);
return new PresentationTextObject(textObjectName);
}


/**
* Creates a new MO:DCA {@link Overlay}.
*
* @param width
* the width of the overlay
* @param height
* the height of the overlay
* @param widthRes
* the width resolution of the overlay
* @param heightRes
* the height resolution of the overlay
* @param overlayRotation
* the rotation of the overlay
*
* @return a new {@link Overlay}.
*/
public Overlay createOverlay(int width, int height,
int widthRes, int heightRes, int overlayRotation) {
String overlayName = OVERLAY_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++overlayCount), '0', 5);
Overlay overlay = new Overlay(this, overlayName, width, height,
overlayRotation, widthRes, heightRes);
return overlay;
}

/**
* Creates a MO:DCA {@link Document}
*
* @return a new {@link Document}
*/
public Document createDocument() {
String documentName = DOCUMENT_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++documentCount), '0', 5);
Document document = new Document(this, documentName);
return document;
}

/**
* Creates a MO:DCA {@link MapCodedFont}
*
* @return a new {@link MapCodedFont}
*/
public MapCodedFont createMapCodedFont() {
MapCodedFont mapCodedFont = new MapCodedFont();
return mapCodedFont;
}

/**
* Creates a MO:DCA {@link IncludePageSegment}
*
* @param name the page segment name
* @param x the x coordinate
* @param y the y coordinate
*
* @return a new {@link IncludePageSegment}
*/
public IncludePageSegment createIncludePageSegment(String name, int x, int y) {
IncludePageSegment includePageSegment = new IncludePageSegment(name, x, y);
return includePageSegment;
}

/**
* Creates a MO:DCA {@link IncludeObject}
*
* @param name the name of this include object
* @return a new {@link IncludeObject}
*/
public IncludeObject createInclude(String name) {
IncludeObject includeObject = new IncludeObject(name);
return includeObject;
}

/**
* Creates a MO:DCA {@link TagLogicalElement}
*
* @param name name of the element
* @param value value of the element
* @return a new {@link TagLogicalElement}
*/
public TagLogicalElement createTagLogicalElement(String name, String value) {
TagLogicalElement tle = new TagLogicalElement(name, value);
return tle;
}

/**
* Creates a new {@link DataStream}
*
* @param paintingState the AFP painting state
* @param outputStream an outputstream to write to
* @return a new {@link DataStream}
*/
public DataStream createDataStream(AFPPaintingState paintingState, OutputStream outputStream) {
DataStream dataStream = new DataStream(this, paintingState, outputStream);
return dataStream;
}

/**
* Creates a new MO:DCA {@link PageDescriptor}
*
* @param width the page width.
* @param height the page height.
* @param widthRes the page width resolution.
* @param heightRes the page height resolution.
* @return a new {@link PageDescriptor}
*/
public PageDescriptor createPageDescriptor(int width, int height, int widthRes, int heightRes) {
PageDescriptor pageDescriptor = new PageDescriptor(width, height, widthRes, heightRes);
return pageDescriptor;
}

/**
* Returns a new MO:DCA {@link ObjectEnvironmentGroup}
*
* @return a new {@link ObjectEnvironmentGroup}
*/
public ObjectEnvironmentGroup createObjectEnvironmentGroup() {
String oegName = OBJECT_ENVIRONMENT_GROUP_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++objectEnvironmentGroupCount), '0', 5);
ObjectEnvironmentGroup objectEnvironmentGroup = new ObjectEnvironmentGroup(oegName);
return objectEnvironmentGroup;
}

/**
* Creates a new GOCA {@link GraphicsData}
*
* @return a new {@link GraphicsData}
*/
public GraphicsData createGraphicsData() {
GraphicsData graphicsData = new GraphicsData();
return graphicsData;
}

/**
* Creates a new {@link ObjectAreaDescriptor}
*
* @param width the object width.
* @param height the object height.
* @param widthRes the object width resolution.
* @param heightRes the object height resolution.
* @return a new {@link ObjectAreaDescriptor}
*/
public ObjectAreaDescriptor createObjectAreaDescriptor(
int width, int height, int widthRes, int heightRes) {
ObjectAreaDescriptor objectAreaDescriptor
= new ObjectAreaDescriptor(width, height, widthRes, heightRes);
return objectAreaDescriptor;
}

/**
* Creates a new {@link ObjectAreaPosition}
*
* @param x the x coordinate.
* @param y the y coordinate.
* @param rotation the coordinate system rotation (must be 0, 90, 180, 270).
* @return a new {@link ObjectAreaPosition}
*/
public ObjectAreaPosition createObjectAreaPosition(int x, int y,
int rotation) {
ObjectAreaPosition objectAreaPosition = new ObjectAreaPosition(
x, y, rotation);
return objectAreaPosition;
}

/**
* Creates a new {@link ImageDataDescriptor}
*
* @param width the image width
* @param height the image height
* @param widthRes the x resolution of the image
* @param heightRes the y resolution of the image
* @return a new {@link ImageDataDescriptor}
*/
public ImageDataDescriptor createImageDataDescriptor(
int width, int height, int widthRes, int heightRes) {
ImageDataDescriptor imageDataDescriptor = new ImageDataDescriptor(
width, height, widthRes, heightRes);
return imageDataDescriptor;
}

/**
* Creates a new GOCA {@link GraphicsDataDescriptor}
*
* @param xlwind the left edge of the graphics window
* @param xrwind the right edge of the graphics window
* @param ybwind the top edge of the graphics window
* @param ytwind the bottom edge of the graphics window
* @param widthRes the x resolution of the graphics window
* @param heightRes the y resolution of the graphics window
* @return a new {@link GraphicsDataDescriptor}
*/
public GraphicsDataDescriptor createGraphicsDataDescriptor(
int xlwind, int xrwind, int ybwind, int ytwind, int widthRes, int heightRes) {
GraphicsDataDescriptor graphicsDataDescriptor = new GraphicsDataDescriptor(
xlwind, xrwind, ybwind, ytwind, widthRes, heightRes);
return graphicsDataDescriptor;
}

/**
* Creates a new MO:DCA {@link ContainerDataDescriptor}
*
* @param dataWidth the container data width
* @param dataHeight the container data height
* @param widthRes the container data width resolution
* @param heightRes the container data height resolution
* @return a new {@link ContainerDataDescriptor}
*/
public ContainerDataDescriptor createContainerDataDescriptor(
int dataWidth, int dataHeight, int widthRes, int heightRes) {
ContainerDataDescriptor containerDataDescriptor
= new ContainerDataDescriptor(dataWidth, dataHeight, widthRes, heightRes);
return containerDataDescriptor;
}

/**
* Creates a new MO:DCA {@link MapContainerData}
*
* @param optionValue the option value
* @return a new {@link MapContainerData}
*/
public MapContainerData createMapContainerData(byte optionValue) {
MapContainerData mapContainerData = new MapContainerData(optionValue);
return mapContainerData;
}

/**
* Creates a new MO:DCA {@link MapDataResource}
*
* @return a new {@link MapDataResource}
*/
public MapDataResource createMapDataResource() {
MapDataResource mapDataResource = new MapDataResource();
return mapDataResource;
}

/**
* Creates a new PTOCA {@link PresentationTextDescriptor}
*
* @return a new {@link PresentationTextDescriptor}
*/
public PresentationTextDescriptor createPresentationTextDataDescriptor(
int width, int height, int widthRes, int heightRes) {
PresentationTextDescriptor presentationTextDescriptor
= new PresentationTextDescriptor(width, height,
widthRes, heightRes);
return presentationTextDescriptor;
}

/**
* Creates a new MO:DCA {@link PresentationEnvironmentControl}
*
* @return a new {@link PresentationEnvironmentControl}
*/
public PresentationEnvironmentControl createPresentationEnvironmentControl() {
PresentationEnvironmentControl presentationEnvironmentControl
= new PresentationEnvironmentControl();
return presentationEnvironmentControl;
}

/**
* Creates a new MO:DCA {@link InvokeMediumMap}
*
* @param name the object name
* @return a new {@link InvokeMediumMap}
*/
public InvokeMediumMap createInvokeMediumMap(String name) {
InvokeMediumMap invokeMediumMap = new InvokeMediumMap(name);
return invokeMediumMap;
}

/**
* Creates a new MO:DCA {@link ResourceEnvironmentGroup}
*
* @return a new {@link ResourceEnvironmentGroup}
*/
public ResourceEnvironmentGroup createResourceEnvironmentGroup() {
ResourceEnvironmentGroup resourceEnvironmentGroup = new ResourceEnvironmentGroup();
return resourceEnvironmentGroup;
}

/**
* Creates a new IOCA {@link ImageSegment}
*
* @return a new {@link ImageSegment}
*/
public ImageSegment createImageSegment() {
String name = IMAGE_SEGMENT_NAME_PREFIX
+ StringUtils.lpad(String.valueOf(++imageSegmentCount), '0', 2);
ImageSegment imageSegment = new ImageSegment(this, name);
return imageSegment;
}

/**
* Creates an new IOCA {@link ImageContent}
*
* @return an {@link ImageContent}
*/
public ImageContent createImageContent() {
ImageContent imageContent = new ImageContent();
return imageContent;
}

/**
* Creates a new IOCA {@link ImageRasterData}
*
* @param rasterData raster data
* @return a new {@link ImageRasterData}
*/
public ImageRasterData createImageRasterData(byte[] rasterData) {
ImageRasterData imageRasterData = new ImageRasterData(rasterData);
return imageRasterData;
}

/**
* Creates an new IOCA {@link ImageSizeParameter}.
*
* @param hsize The horizontal size of the image.
* @param vsize The vertical size of the image.
* @param hresol The horizontal resolution of the image.
* @param vresol The vertical resolution of the image.
* @return a new {@link ImageSizeParameter}
*/
public ImageSizeParameter createImageSizeParameter(int hsize, int vsize,
int hresol, int vresol) {
ImageSizeParameter imageSizeParameter
= new ImageSizeParameter(hsize, vsize, hresol, vresol);
return imageSizeParameter;
}

}

+ 27
- 0
src/java/org/apache/fop/afp/PaintingInfo.java View File

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

/* $Id$ */

package org.apache.fop.afp;

/**
* Generic painting information interface
*/
public interface PaintingInfo {

}

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

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

/* $Id$ */

package org.apache.fop.afp;


/**
* Filled rectangle painting information
*/
public class RectanglePaintingInfo implements PaintingInfo {

private final float x;
private final float y;
private final float width;
private final float height;

/**
* Main constructor
*
* @param x the x coordinate
* @param y the y coordinate
* @param width the width
* @param height the height
*/
public RectanglePaintingInfo(float x, float y, float width, float height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}

/**
* Returns the x coordinate
*
* @return the x coordinate
*/
protected float getX() {
return x;
}

/**
* Returns the y coordinate
*
* @return the y coordinate
*/
protected float getY() {
return y;
}

/**
* Returns the width
*
* @return the width
*/
protected float getWidth() {
return width;
}

/**
* Returns the height
*
* @return the height
*/
protected float getHeight() {
return height;
}

}

+ 40
- 0
src/java/org/apache/fop/afp/Startable.java View File

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

/* $Id$ */

package org.apache.fop.afp;

/**
* Set and expose whether an object has started or not.
*/
public interface Startable {

/**
* Sets whether or not this object has started or not
*
* @param complete true if this object has started
*/
void setStarted(boolean started);

/**
* Returns true if this object has started
*
* @return true if this object has started
*/
boolean isStarted();
}

+ 38
- 0
src/java/org/apache/fop/afp/Streamable.java View File

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

/* $Id$ */

package org.apache.fop.afp;

import java.io.IOException;
import java.io.OutputStream;

/**
* Implementing object is able to write to an OutputStream
*/
public interface Streamable {

/**
* DataStream objects must implement the writeToStream()
* method to write its data to the given OutputStream
*
* @param os the outputsteam stream
* @throws java.io.IOException an I/O exception of some sort has occurred.
*/
void writeToStream(OutputStream os) throws IOException;
}

+ 33
- 0
src/java/org/apache/fop/afp/StructuredData.java View File

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

/* $Id$ */

package org.apache.fop.afp;

/**
* An AFP object which is able to know its own data length prior to writeToStream()
*/
public interface StructuredData {

/**
* Returns the data length of this structured field
*
* @return the data length of this structured field
*/
int getDataLength();
}

+ 157
- 0
src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java View File

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

/* $Id$ */

package org.apache.fop.afp.fonts;

import org.apache.fop.fonts.Base14Font;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.base14.Courier;
import org.apache.fop.fonts.base14.CourierBold;
import org.apache.fop.fonts.base14.CourierBoldOblique;
import org.apache.fop.fonts.base14.CourierOblique;
import org.apache.fop.fonts.base14.Helvetica;
import org.apache.fop.fonts.base14.HelveticaBold;
import org.apache.fop.fonts.base14.HelveticaOblique;
import org.apache.fop.fonts.base14.TimesBold;
import org.apache.fop.fonts.base14.TimesBoldItalic;
import org.apache.fop.fonts.base14.TimesItalic;
import org.apache.fop.fonts.base14.TimesRoman;

/**
* Sets up a typical Base 12 font configuration for AFP
*/
public class AFPBase12FontCollection implements FontCollection {

/** standard raster font sizes */
private static final int[] RASTER_SIZES = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 30, 36};

/** standard raster font charset references */
private static final String[] CHARSET_REF = {
"60", "70", "80", "90", "00", "A0", "B0", "D0", "F0", "H0", "J0", "N0", "T0", "Z0"};

private void addCharacterSet(RasterFont font, String charsetName, Base14Font base14) {
for (int i = 0; i < RASTER_SIZES.length; i++) {
int size = RASTER_SIZES[i];
FopCharacterSet characterSet = new FopCharacterSet(
CharacterSet.DEFAULT_CODEPAGE, CharacterSet.DEFAULT_ENCODING,
charsetName + CHARSET_REF[i], size, base14);
font.addCharacterSet(size, characterSet);
}
}

private int addFontProperties(FontInfo fontInfo, AFPFont font,
String[] names, String style, int weight, int num) {
String internalFontKey = "F" + num;
fontInfo.addMetrics(internalFontKey, font);
fontInfo.addFontProperties(internalFontKey, names, style, weight);
num++;
return num;
}

/** {@inheritDoc} */
public int setup(int start, FontInfo fontInfo) {

/**
* Add the base 12 fonts (Helvetica, Times and Courier)
*
* Note: this default font configuration may not be available
* on your AFP environment.
*/
int num = start;
RasterFont font = null;

/** standard font family reference names for Helvetica font */
final String[] helveticaNames = {"Helvetica", "Arial", "sans-serif"};
font = new RasterFont("Helvetica");
addCharacterSet(font, "C0H200", new Helvetica());
num = addFontProperties(fontInfo, font, helveticaNames,
Font.STYLE_NORMAL, Font.WEIGHT_NORMAL, num);

font = new RasterFont("Helvetica Italic");
addCharacterSet(font, "C0H300", new HelveticaOblique());
num = addFontProperties(fontInfo, font, helveticaNames,
Font.STYLE_ITALIC, Font.WEIGHT_NORMAL, num);

font = new RasterFont("Helvetica (Semi) Bold");
addCharacterSet(font, "C0H400", new HelveticaBold());
num = addFontProperties(fontInfo, font, helveticaNames,
Font.STYLE_NORMAL, Font.WEIGHT_BOLD, num);

font = new RasterFont("Helvetica Italic (Semi) Bold");
addCharacterSet(font, "C0H500", new HelveticaOblique());
num = addFontProperties(fontInfo, font, helveticaNames,
Font.STYLE_ITALIC, Font.WEIGHT_BOLD, num);


/** standard font family reference names for Times font */

/** any is treated as serif */
final String[] timesNames = {"Times", "TimesRoman", "Times Roman", "Times-Roman",
"Times New Roman", "TimesNewRoman", "serif", "any"};

font = new RasterFont("Times Roman");
addCharacterSet(font, "CON200", new TimesRoman());
num = addFontProperties(fontInfo, font, timesNames,
Font.STYLE_NORMAL, Font.WEIGHT_NORMAL, num);

font = new RasterFont("Times Roman Italic");
addCharacterSet(font, "CON300", new TimesItalic());
num = addFontProperties(fontInfo, font, timesNames,
Font.STYLE_ITALIC, Font.WEIGHT_NORMAL, num);

font = new RasterFont("Times Roman Bold");
addCharacterSet(font, "CON400", new TimesBold());
num = addFontProperties(fontInfo, font, timesNames,
Font.STYLE_NORMAL, Font.WEIGHT_BOLD, num);

font = new RasterFont("Times Roman Italic Bold");
addCharacterSet(font, "CON500", new TimesBoldItalic());
num = addFontProperties(fontInfo, font, timesNames,
Font.STYLE_ITALIC, Font.WEIGHT_BOLD, num);


/** standard font family reference names for Courier font */
final String[] courierNames = {"Courier", "monospace"};

font = new RasterFont("Courier");
addCharacterSet(font, "C04200", new Courier());
num = addFontProperties(fontInfo, font, courierNames,
Font.STYLE_NORMAL, Font.WEIGHT_NORMAL, num);

font = new RasterFont("Courier Italic");
addCharacterSet(font, "C04300", new CourierOblique());
num = addFontProperties(fontInfo, font, courierNames,
Font.STYLE_ITALIC, Font.WEIGHT_NORMAL, num);

font = new RasterFont("Courier Bold");
addCharacterSet(font, "C04400", new CourierBold());
num = addFontProperties(fontInfo, font, courierNames,
Font.STYLE_NORMAL, Font.WEIGHT_BOLD, num);

font = new RasterFont("Courier Italic Bold");
addCharacterSet(font, "C04500", new CourierBoldOblique());
num = addFontProperties(fontInfo, font, courierNames,
Font.STYLE_ITALIC, Font.WEIGHT_BOLD, num);

return num;
}

}

src/java/org/apache/fop/render/afp/fonts/AFPFont.java → src/java/org/apache/fop/afp/fonts/AFPFont.java View File

@@ -17,7 +17,8 @@

/* $Id$ */

package org.apache.fop.render.afp.fonts;
package org.apache.fop.afp.fonts;

import java.util.Map;
import java.util.Set;

@@ -41,7 +42,6 @@ public abstract class AFPFont extends Typeface {
*/
public AFPFont(String name) {
this.name = name;

}

/** {@inheritDoc} */
@@ -106,4 +106,8 @@ public abstract class AFPFont extends Typeface {
return true;
}

/** {@inheritDoc} */
public String toString() {
return "name=" + name;
}
}

src/java/org/apache/fop/render/afp/AFPFontAttributes.java → src/java/org/apache/fop/afp/fonts/AFPFontAttributes.java View File

@@ -17,40 +17,30 @@

/* $Id$ */

package org.apache.fop.render.afp;

import org.apache.fop.render.afp.fonts.AFPFont;
package org.apache.fop.afp.fonts;

/**
* This class encapsulates the font attributes that need to be included
* in the AFP data stream. This class does not assist in converting the
* font attributes to AFP code pages and character set values.
*
*/
public class AFPFontAttributes {

/**
* The font reference
*/
/** the font reference */
private int fontReference;

/**
* The font key
*/
private String fontKey;
/** the font key */
private final String fontKey;

/**
* The font
*/
private AFPFont font;
/** the font */
private final AFPFont font;

/**
* The point size
*/
private int pointSize;
/** the point size */
private final int pointSize;

/**
* Constructor for the AFPFontAttributes
*
* @param fontKey the font key
* @param font the font
* @param pointSize the point size
@@ -62,6 +52,8 @@ public class AFPFontAttributes {
}

/**
* Return the font
*
* @return the font
*/
public AFPFont getFont() {
@@ -69,6 +61,8 @@ public class AFPFontAttributes {
}

/**
* Return the FontKey attribute
*
* @return the FontKey attribute
*/
public String getFontKey() {
@@ -76,6 +70,8 @@ public class AFPFontAttributes {
}

/**
* Return the point size attribute
*
* @return the point size attribute
*/
public int getPointSize() {
@@ -83,6 +79,8 @@ public class AFPFontAttributes {
}

/**
* Return the FontReference attribute
*
* @return the FontReference attribute
*/
public int getFontReference() {
@@ -91,10 +89,18 @@ public class AFPFontAttributes {

/**
* Sets the FontReference attribute
*
* @param fontReference the FontReference to set
*/
public void setFontReference(int fontReference) {
this.fontReference = fontReference;
}

/** {@inheritDoc} */
public String toString() {
return "fontReference=" + fontReference
+ ", fontKey=" + fontKey
+ ", font=" + font
+ ", pointSize=" + pointSize;
}
}

+ 92
- 0
src/java/org/apache/fop/afp/fonts/AFPFontCollection.java View File

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

/* $Id$ */

package org.apache.fop.afp.fonts;

import java.util.Iterator;
import java.util.List;

import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;

/**
* A base collection of AFP fonts
*/
public class AFPFontCollection implements FontCollection {

private final EventBroadcaster eventBroadcaster;

private final List/*<AFPFontInfo>*/ fontInfoList;

/**
* Main constructor
*
* @param eventBroadcaster the event broadcaster
* @param fontInfoList the font info list
*/
public AFPFontCollection(EventBroadcaster eventBroadcaster,
List/*<AFPFontInfo>*/ fontInfoList) {
this.eventBroadcaster = eventBroadcaster;
this.fontInfoList = fontInfoList;
}

/** {@inheritDoc} */
public int setup(int start, FontInfo fontInfo) {
int num = 1;
AFPEventProducer eventProducer = AFPEventProducer.Provider.get(eventBroadcaster);
if (fontInfoList != null && fontInfoList.size() > 0) {
for (Iterator it = fontInfoList.iterator(); it.hasNext();) {
AFPFontInfo afpFontInfo = (AFPFontInfo)it.next();
AFPFont afpFont = afpFontInfo.getAFPFont();
List/*<FontTriplet>*/ tripletList = afpFontInfo.getFontTriplets();
for (Iterator it2 = tripletList.iterator(); it2.hasNext();) {
FontTriplet triplet = (FontTriplet)it2.next();
fontInfo.addFontProperties("F" + num,
triplet.getName(), triplet.getStyle(), triplet.getWeight());
fontInfo.addMetrics("F" + num, afpFont);
num++;
}
}
if (fontInfo.fontLookup("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL) == null) {
eventProducer.warnMissingDefaultFont(this, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
}
if (fontInfo.fontLookup("any", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL) == null) {
eventProducer.warnMissingDefaultFont(this, Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
}
if (fontInfo.fontLookup("any", Font.STYLE_NORMAL, Font.WEIGHT_BOLD) == null) {
eventProducer.warnMissingDefaultFont(this, Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
}
if (fontInfo.fontLookup("any", Font.STYLE_ITALIC, Font.WEIGHT_BOLD) == null) {
eventProducer.warnMissingDefaultFont(this, Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
}
} else {
eventProducer.warnDefaultFontSetup(this);

// Go with a default base 12 configuration for AFP environments
FontCollection base12FontCollection = new AFPBase12FontCollection();
num = base12FontCollection.setup(num, fontInfo);
}
return num;
}

}

src/java/org/apache/fop/render/afp/fonts/AFPFontInfo.java → src/java/org/apache/fop/afp/fonts/AFPFontInfo.java View File

@@ -17,30 +17,33 @@

/* $Id$ */

package org.apache.fop.render.afp.fonts;
package org.apache.fop.afp.fonts;

import java.util.List;


/**
* FontInfo contains meta information on fonts
*/
public class AFPFontInfo {

private AFPFont font;
private List fontTriplets;
private List/*<FontTriplet>*/ tripletList;

/**
* Main constructor
*
* @param afpFont The AFP Font
* @param fontTriplets List of font triplets to associate with this font
* @param tripletList List of font triplets to associate with this font
*/
public AFPFontInfo(AFPFont afpFont, List fontTriplets) {
public AFPFontInfo(AFPFont afpFont, List/*<FontTriplet>*/ tripletList) {
this.font = afpFont;
this.fontTriplets = fontTriplets;
this.tripletList = tripletList;
}

/**
* Returns the afp font
*
* @return the afp font
*/
public AFPFont getAFPFont() {
@@ -49,10 +52,11 @@ public class AFPFontInfo {

/**
* Returns the list of font triplets associated with this font.
*
* @return List of font triplets
*/
public List getFontTriplets() {
return fontTriplets;
public List/*<FontTriplet>*/ getFontTriplets() {
return tripletList;
}

}

src/java/org/apache/fop/render/afp/fonts/AFPFontReader.java → src/java/org/apache/fop/afp/fonts/AFPFontReader.java View File

@@ -17,7 +17,7 @@

/* $Id$ */

package org.apache.fop.render.afp.fonts;
package org.apache.fop.afp.fonts;

import java.io.File;
import java.io.FileNotFoundException;
@@ -31,8 +31,8 @@ import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.render.afp.modca.AFPConstants;
import org.apache.fop.render.afp.tools.StructuredFieldReader;
import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.util.StructuredFieldReader;

/**
* The AFPFontReader is responsible for reading the font attributes from binary
@@ -56,7 +56,7 @@ public final class AFPFontReader {
/**
* Static logging instance
*/
protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.fonts");
protected static final Log log = LogFactory.getLog("org.apache.xmlgraphics.afp.fonts");

/**
* Template used to convert lists to arrays.

+ 64
- 0
src/java/org/apache/fop/afp/fonts/AFPPageFonts.java View File

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

/* $Id$ */

package org.apache.fop.afp.fonts;

/**
* Holds the current page fonts
*/
public class AFPPageFonts extends java.util.HashMap {
private static final long serialVersionUID = -4991896259427109041L;

/**
* Default constructor
*/
public AFPPageFonts() {
super();
}

/**
* Parameterized constructor
*
* @param fonts an existing set of afp page fonts
*/
public AFPPageFonts(AFPPageFonts fonts) {
super(fonts);
}

/**
* Registers a font on the current page and returns font attributes
*
* @param fontName the internal font name
* @param font the AFPFont
* @param fontSize the font point size
* @return newly registered AFPFontAttributes
*/
public AFPFontAttributes registerFont(String fontName, AFPFont font, int fontSize) {
String pageFontKey = fontName + "_" + fontSize;
AFPFontAttributes afpFontAttributes = (AFPFontAttributes)super.get(pageFontKey);
// Add to page font mapping if not already present
if (afpFontAttributes == null) {
afpFontAttributes = new AFPFontAttributes(fontName, font, fontSize);
super.put(pageFontKey, afpFontAttributes);
int fontRef = super.size();
afpFontAttributes.setFontReference(fontRef);
}
return afpFontAttributes;
}
}

src/java/org/apache/fop/render/afp/fonts/CharacterSet.java → src/java/org/apache/fop/afp/fonts/CharacterSet.java View File

@@ -17,7 +17,7 @@

/* $Id$ */

package org.apache.fop.render.afp.fonts;
package org.apache.fop.afp.fonts;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -25,8 +25,8 @@ import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.render.afp.modca.AFPConstants;
import org.apache.fop.render.afp.tools.StringUtils;
import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.util.StringUtils;

/**
* The IBM Font Object Content Architecture (FOCA) supports presentation
@@ -51,10 +51,10 @@ public class CharacterSet {
protected static final Log log = LogFactory.getLog(CharacterSet.class.getName());

/** default codepage */
protected static final String DEFAULT_CODEPAGE = "T1V10500";
public static final String DEFAULT_CODEPAGE = "T1V10500";

/** default encoding */
protected static final String DEFAULT_ENCODING = "Cp500";
public static final String DEFAULT_ENCODING = "Cp500";

private static final int MAX_NAME_LEN = 8;


src/java/org/apache/fop/render/afp/fonts/CharacterSetOrientation.java → src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java View File

@@ -17,7 +17,7 @@

/* $Id$ */

package org.apache.fop.render.afp.fonts;
package org.apache.fop.afp.fonts;

/**
* The IBM Font Object Content Architecture (FOCA) supports presentation

src/java/org/apache/fop/render/afp/exceptions/FontRuntimeException.java → src/java/org/apache/fop/afp/fonts/FontRuntimeException.java View File

@@ -17,13 +17,15 @@

/* $Id$ */

package org.apache.fop.render.afp.exceptions;
package org.apache.fop.afp.fonts;

/**
* A runtime exception for handling fatal errors in processing fonts.
* <p/>
*/
public class FontRuntimeException extends NestedRuntimeException {
public class FontRuntimeException extends RuntimeException {

private static final long serialVersionUID = -2217420523816384707L;

/**
* Constructs a FontRuntimeException with the specified message.

src/java/org/apache/fop/render/afp/fonts/FopCharacterSet.java → src/java/org/apache/fop/afp/fonts/FopCharacterSet.java View File

@@ -17,7 +17,7 @@

/* $Id$ */

package org.apache.fop.render.afp.fonts;
package org.apache.fop.afp.fonts;

import org.apache.fop.fonts.Typeface;


src/java/org/apache/fop/render/afp/fonts/OutlineFont.java → src/java/org/apache/fop/afp/fonts/OutlineFont.java View File

@@ -17,7 +17,8 @@

/* $Id$ */

package org.apache.fop.render.afp.fonts;
package org.apache.fop.afp.fonts;


/**
* A font defined as a set of lines and curves as opposed to a bitmap font. An

src/java/org/apache/fop/render/afp/fonts/RasterFont.java → src/java/org/apache/fop/afp/fonts/RasterFont.java View File

@@ -17,18 +17,14 @@

/* $Id$ */

package org.apache.fop.render.afp.fonts;
package org.apache.fop.afp.fonts;

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

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

import org.apache.fop.fo.properties.FixedLength;
import org.apache.fop.render.afp.exceptions.FontRuntimeException;

/**
* A font where each character is stored as an array of pixels (a bitmap). Such
* fonts are not easily scalable, in contrast to vectored fonts. With this type
@@ -39,9 +35,10 @@ import org.apache.fop.render.afp.exceptions.FontRuntimeException;
public class RasterFont extends AFPFont {

/** Static logging instance */
protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.fonts");
protected static final Log log = LogFactory.getLog("org.apache.fop.afp.fonts");

private Map charSets = new HashMap();
private final Map/*<String,CharacterSet>*/ charSets
= new java.util.HashMap/*<String,CharacterSet>*/();

private CharacterSet charSet = null;

@@ -66,6 +63,9 @@ public class RasterFont extends AFPFont {
this.charSet = characterSet;
}

/** Describes the unit millipoint. */
public static final String MPT = "mpt";

/**
* Get the character set metrics for the specified point size.
*
@@ -77,7 +77,7 @@ public class RasterFont extends AFPFont {
String pointsize = String.valueOf(size / 1000);
CharacterSet csm = (CharacterSet) charSets.get(pointsize);
if (csm == null) {
csm = (CharacterSet) charSets.get(size + FixedLength.MPT);
csm = (CharacterSet) charSets.get(size + MPT);
}
if (csm == null) {
// Get char set with nearest font size
@@ -85,7 +85,7 @@ public class RasterFont extends AFPFont {
for (Iterator it = charSets.entrySet().iterator(); it.hasNext();) {
Map.Entry me = (Map.Entry)it.next();
String key = (String)me.getKey();
if (!key.endsWith(FixedLength.MPT)) {
if (!key.endsWith(MPT)) {
int mpt = Integer.parseInt(key) * 1000;
if (Math.abs(size - mpt) < distance) {
distance = Math.abs(size - mpt);
@@ -95,7 +95,7 @@ public class RasterFont extends AFPFont {
}
}
if (csm != null) {
charSets.put(size + FixedLength.MPT, csm);
charSets.put(size + MPT, csm);
String msg = "No " + (size / 1000) + "pt font " + getFontName()
+ " found, substituted with " + pointsize + "pt font";
log.warn(msg);

+ 23
- 0
src/java/org/apache/fop/afp/fonts/package.html View File

@@ -0,0 +1,23 @@
<!--
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.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
<HTML>
<TITLE>org.apache.fop.afp.goca Package</TITLE>
<BODY>
<P>Contains a collection of AFP Graphics Object Content Architecture (GOCA) structured objects.</P>
</BODY>
</HTML>

+ 149
- 0
src/java/org/apache/fop/afp/goca/AbstractGraphicsCoord.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.util.BinaryUtils;

/**
* A base class encapsulating the structure of coordinate based GOCA objects
*/
public abstract class AbstractGraphicsCoord extends AbstractGraphicsDrawingOrder {

/** array of x/y coordinates */
protected int[] coords = null;

protected boolean relative = false;

/**
* Constructor
*
* @param coords the x/y coordinates for this object
*/
public AbstractGraphicsCoord(int[] coords) {
if (coords == null) {
relative = true;
} else {
this.coords = coords;
}
}

/**
* Constructor
*
* @param coords the x/y coordinates for this object
* @param relative
*/
public AbstractGraphicsCoord(int[] coords, boolean relative) {
this(coords);
this.relative = relative;
}

/**
* Constructor
*
* @param x the x coordinate for this object
* @param y the y coordinate for this object
*/
public AbstractGraphicsCoord(int x, int y) {
this(new int[] {x, y});
}

/**
* Constructor
*
* @param x1 the x1 coordinate for this object
* @param y1 the y1 coordinate for this object
* @param x2 the x2 coordinate for this object
* @param y2 the y2 coordinate for this object
*/
public AbstractGraphicsCoord(int x1, int y1, int x2, int y2) {
this(new int[] {x1, y1, x2, y2});
}

/** {@inheritDoc} */
public int getDataLength() {
return 2 + (coords != null ? coords.length * 2 : 0);
}

/**
* Returns the coordinate data start index
*
* @return the coordinate data start index
*/
int getCoordinateDataStartIndex() {
return 2;
}

/**
* Returns the coordinate data
*
* @return the coordinate data
*/
byte[] getData() {
byte[] data = super.getData();
if (coords != null) {
addCoords(data, getCoordinateDataStartIndex());
}
return data;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
os.write(getData());
}

/**
* Adds the coordinates to the structured field data
*
* @param data the structured field data
* @param fromIndex the start index
*/
protected void addCoords(byte[] data, int fromIndex) {
// X/Y POS
for (int i = 0; i < coords.length; i++, fromIndex += 2) {
byte[] coord = BinaryUtils.convert(coords[i], 2);
data[fromIndex] = coord[0];
data[fromIndex + 1] = coord[1];
}
}

/** {@inheritDoc} */
public String toString() {
String coordsStr = "";
for (int i = 0; i < coords.length; i++) {
coordsStr += (i % 2 == 0) ? "x" : "y";
coordsStr += (i / 2) + "=" + coords[i] + ",";
}
coordsStr = coordsStr.substring(0, coordsStr.length() - 1);
return getName() + "{" + coordsStr + "}";
}

/**
* Returns true if this is a relative drawing order
*
* @return true if this is a relative drawing order
*/
protected boolean isRelative() {
return this.relative;
}
}

+ 60
- 0
src/java/org/apache/fop/afp/goca/AbstractGraphicsDrawingOrder.java View File

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

/* $Id$ */

package org.apache.fop.afp.goca;

import org.apache.fop.afp.StructuredData;
import org.apache.fop.afp.modca.AbstractAFPObject;

/**
* A base GOCA drawing order
*/
public abstract class AbstractGraphicsDrawingOrder extends AbstractAFPObject
implements StructuredData {

/**
* Returns the order code of this structured field
*
* @return the order code of this structured field
*/
abstract byte getOrderCode();

/**
* Returns the coordinate data
*
* @return the coordinate data
*/
byte[] getData() {
int len = getDataLength();
byte[] data = new byte[len];
data[0] = getOrderCode();
data[1] = (byte)(len - 2);
return data;
}

/**
* Returns the short name of this GOCA object
*
* @return the short name of this GOCA object
*/
public String getName() {
String className = getClass().getName();
return className.substring(className.lastIndexOf(".") + 1);
}
}

+ 158
- 0
src/java/org/apache/fop/afp/goca/AbstractGraphicsDrawingOrderContainer.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Startable;
import org.apache.fop.afp.StructuredData;
import org.apache.fop.afp.modca.AbstractNamedAFPObject;

/**
* A base container of prepared structured AFP objects
*/
public abstract class AbstractGraphicsDrawingOrderContainer extends AbstractNamedAFPObject
implements StructuredData, Completable, Startable {

/** list of objects contained within this container */
protected List/*<StructuredDataObject>*/ objects
= new java.util.ArrayList/*<StructuredDataObject>*/();

/** object is complete */
private boolean complete = false;

/** object has started */
private boolean started = false;

/**
* Default constructor
*/
protected AbstractGraphicsDrawingOrderContainer() {
}

/**
* Named constructor
*
* @param name the name of the container
*/
protected AbstractGraphicsDrawingOrderContainer(String name) {
super(name);
}

/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
setStarted(true);
}

/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
writeObjects(objects, os);
}

/**
* Adds a given graphics object to this container
*
* @param object the structured data object
*/
public void addObject(StructuredData object) {
objects.add(object);
}

/**
* Adds all the contents of a given graphics container to this container
*
* @param graphicsContainer a graphics container
*/
public void addAll(AbstractGraphicsDrawingOrderContainer graphicsContainer) {
Collection/*<StructuredDataObject>*/ objects = graphicsContainer.getObjects();
objects.addAll(objects);
}

/**
* Returns all the objects in this container
*
* @return all the objects in this container
*/
private Collection getObjects() {
return this.objects;
}

/**
* Removes the last drawing order from this container and returns it
*
* @return the last drawing order from this container or null if empty
*/
public StructuredData removeLast() {
int lastIndex = objects.size() - 1;
StructuredData object = null;
if (lastIndex > -1) {
object = (StructuredData)objects.get(lastIndex);
objects.remove(lastIndex);
}
return object;
}

/**
* Returns the current data length
*
* @return the current data length of this container including
* all enclosed objects (and their containers)
*/
public int getDataLength() {
int dataLen = 0;
Iterator it = objects.iterator();
while (it.hasNext()) {
dataLen += ((StructuredData)it.next()).getDataLength();
}
return dataLen;
}

/** {@inheritDoc} */
public void setComplete(boolean complete) {
Iterator it = objects.iterator();
while (it.hasNext()) {
Object object = it.next();
if (object instanceof Completable) {
((Completable)object).setComplete(true);
}
}
this.complete = true;
}

/** {@inheritDoc} */
public boolean isComplete() {
return this.complete;
}

/** {@inheritDoc} */
public boolean isStarted() {
return this.started;
}

/** {@inheritDoc} */
public void setStarted(boolean started) {
this.started = started;
}
}

+ 69
- 0
src/java/org/apache/fop/afp/goca/GraphicsAreaBegin.java View File

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

/* $Id$ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

/**
* The beginning of a filled region (graphics area).
*/
public class GraphicsAreaBegin extends AbstractGraphicsDrawingOrder {

private static final int RES1 = 1;
private static final int BOUNDARY = 2;
private static final int NO_BOUNDARY = 0;

/** draw boundary lines around this area */
private boolean drawBoundary = false;

/**
* Sets whether boundary lines are drawn
*
* @param drawBoundaryLines whether boundary lines are drawn
*/
public void setDrawBoundaryLines(boolean drawBoundaryLines) {
this.drawBoundary = drawBoundaryLines;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
getOrderCode(), // GBAR order code
(byte)(RES1 + (drawBoundary ? BOUNDARY : NO_BOUNDARY))
};
os.write(data);
}

/** {@inheritDoc} */
public int getDataLength() {
return 2;
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsAreaBegin{drawBoundary=" + drawBoundary + "}";
}

/** {@inheritDoc} */
byte getOrderCode() {
return 0x68;
}
}

+ 53
- 0
src/java/org/apache/fop/afp/goca/GraphicsAreaEnd.java View File

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

/* $Id$ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

/**
* The end of a filled region (graphics area).
*/
public class GraphicsAreaEnd extends AbstractGraphicsDrawingOrder {

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
getOrderCode(), // GEAR order code
0x00, // LENGTH
};
os.write(data);
}

/** {@inheritDoc} */
public int getDataLength() {
return 2;
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsAreaEnd";
}

/** {@inheritDoc} */
byte getOrderCode() {
return 0x60;
}
}

+ 63
- 0
src/java/org/apache/fop/afp/goca/GraphicsBox.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

/**
* A GOCA graphics rectangular box
*/
public final class GraphicsBox extends AbstractGraphicsCoord {

/**
* Constructor
*
* @param coords the x/y coordinates for this object
*/
public GraphicsBox(int[] coords) {
super(coords);
}

/** {@inheritDoc} */
public int getDataLength() {
return 12;
}

/** {@inheritDoc} */
int getCoordinateDataStartIndex() {
return 4;
}

/** {@inheritDoc} */
byte getOrderCode() {
return (byte)0xC0;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = getData();
data[2] = (byte)0x20; // CONTROL draw control flags
data[3] = 0x00; // reserved

os.write(data);
}

}

+ 112
- 0
src/java/org/apache/fop/afp/goca/GraphicsChainedSegment.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.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.util.BinaryUtils;

/**
* A GOCA graphics segment
*/
public final class GraphicsChainedSegment extends AbstractGraphicsDrawingOrderContainer {

/** The maximum segment data length */
protected static final int MAX_DATA_LEN = 8192;

private byte[] predecessorNameBytes;

/**
* Main constructor
*
* @param name
* the name of this graphics segment
*/
public GraphicsChainedSegment(String name) {
super(name);
}

/**
* Constructor
*
* @param name
* the name of this graphics segment
* @param predecessorNameBytes
* the name of the predecessor in this chain
*/
public GraphicsChainedSegment(String name, byte[] predecessorNameBytes) {
super(name);
this.predecessorNameBytes = predecessorNameBytes;
}

/** {@inheritDoc} */
public int getDataLength() {
return 14 + super.getDataLength();
}

private static final byte APPEND_NEW_SEGMENT = 0;
// private static final byte PROLOG = 4;
// private static final byte APPEND_TO_EXISING = 48;

private static final int NAME_LENGTH = 4;

/** {@inheritDoc} */
protected int getNameLength() {
return NAME_LENGTH;
}

/** {@inheritDoc} */
byte getOrderCode() {
return 0x70;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[14];
data[0] = getOrderCode(); // BEGIN_SEGMENT
data[1] = 0x0C; // Length of following parameters

// segment name
byte[] nameBytes = getNameBytes();
System.arraycopy(nameBytes, 0, data, 2, NAME_LENGTH);

data[6] = 0x00; // FLAG1 (ignored)
data[7] = APPEND_NEW_SEGMENT;

int dataLength = super.getDataLength();
byte[] len = BinaryUtils.convert(dataLength, 2);
data[8] = len[0]; // SEGL
data[9] = len[1];

// P/S NAME (predecessor name)
if (predecessorNameBytes != null) {
System.arraycopy(predecessorNameBytes, 0, data, 10, NAME_LENGTH);
}
os.write(data);

writeObjects(objects, os);
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsChainedSegment(name=" + super.getName() + ")";
}
}

+ 114
- 0
src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import org.apache.fop.afp.AFPConstants;

/**
* A GOCA graphics string
*/
public class GraphicsCharacterString extends AbstractGraphicsCoord {

/** Up to 255 bytes of character data */
protected static final int MAX_STR_LEN = 255;

/** the string to draw */
protected final String str;

/**
* Constructor (absolute positioning)
*
* @param str the character string
* @param x the x coordinate
* @param y the y coordinate
*/
public GraphicsCharacterString(String str, int x, int y) {
super(x, y);
this.str = truncate(str);
}

/**
* Constructor (relative positioning)
*
* @param str the character string
* @param x the x coordinate
* @param y the y coordinate
*/
public GraphicsCharacterString(String str) {
super(null);
this.str = truncate(str);
}

/** {@inheritDoc} */
byte getOrderCode() {
if (isRelative()) {
return (byte)0x83;
} else {
return (byte)0xC3;
}
}

/** {@inheritDoc} */
public int getDataLength() {
return super.getDataLength() + str.length();
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = getData();
byte[] strData = getStringAsBytes();
System.arraycopy(strData, 0, data, 6, strData.length);
os.write(data);
}

/**
* Truncates the string as necessary
*
* @param str a character string
* @return a possibly truncated string
*/
private String truncate(String str) {
if (str.length() > MAX_STR_LEN) {
str = str.substring(0, MAX_STR_LEN);
log.warn("truncated character string, longer than " + MAX_STR_LEN + " chars");
}
return str;
}

/**
* Returns the text string as an encoded byte array
*
* @return the text string as an encoded byte array
*/
private byte[] getStringAsBytes() throws UnsupportedEncodingException {
return str.getBytes(AFPConstants.EBCIDIC_ENCODING);
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsCharacterString{"
+ (coords != null ? "x=" + coords[0] + ", y=" + coords[1] : "")
+ "str='" + str + "'" + "}";
}
}

+ 126
- 0
src/java/org/apache/fop/afp/goca/GraphicsData.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.StructuredData;
import org.apache.fop.afp.util.BinaryUtils;
import org.apache.fop.afp.util.StringUtils;

/**
* A GOCA graphics data
*/
public final class GraphicsData extends AbstractGraphicsDrawingOrderContainer {

/** the maximum graphics data length */
public static final int MAX_DATA_LEN = 32767;

/** the graphics segment */
private GraphicsChainedSegment currentSegment = null;

/**
* Main constructor
*/
public GraphicsData() {
}

/** {@inheritDoc} */
public int getDataLength() {
return 8 + super.getDataLength();
}

/**
* Returns a new segment name
*
* @return a new segment name
*/
public String createSegmentName() {
return StringUtils.lpad(String.valueOf(
(super.objects != null ? super.objects.size() : 0) + 1),
'0', 4);
}

/**
* Creates a new graphics segment
*
* @return a newly created graphics segment
*/
public GraphicsChainedSegment newSegment() {
String segmentName = createSegmentName();
if (currentSegment == null) {
currentSegment = new GraphicsChainedSegment(segmentName);
} else {
currentSegment.setComplete(true);
currentSegment = new GraphicsChainedSegment(segmentName, currentSegment.getNameBytes());
}
super.addObject(currentSegment);
return currentSegment;
}

/** {@inheritDoc} */
public void addObject(StructuredData object) {
if (currentSegment == null
|| (currentSegment.getDataLength() + object.getDataLength())
>= GraphicsChainedSegment.MAX_DATA_LEN) {
newSegment();
}
currentSegment.addObject(object);
}

/**
* Removes the current segment from this graphics data
*
* @return the current segment from this graphics data
*/
public StructuredData removeCurrentSegment() {
this.currentSegment = null;
return super.removeLast();
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[9];
copySF(data, SF_CLASS, Type.DATA, Category.GRAPHICS);
int dataLength = getDataLength();
byte[] len = BinaryUtils.convert(dataLength, 2);
data[1] = len[0]; // Length byte 1
data[2] = len[1]; // Length byte 2
os.write(data);

writeObjects(objects, os);
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsData";
}

/**
* Adds the given segment to this graphics data
*
* @param segment a graphics chained segment
*/
public void addSegment(GraphicsChainedSegment segment) {
currentSegment = segment;
super.addObject(currentSegment);
}
}

+ 46
- 0
src/java/org/apache/fop/afp/goca/GraphicsFillet.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

/**
* A GOCA graphics curved tangential line to a specified set of
* straight lines drawn from the given position or current position
*/
public final class GraphicsFillet extends AbstractGraphicsCoord {

/**
* Constructor
*
* @param coords the x/y coordinates for this object
*/
public GraphicsFillet(int[] coords, boolean relative) {
super(coords, relative);
}

/** {@inheritDoc} */
byte getOrderCode() {
if (isRelative()) {
return (byte)0x85;
} else {
return (byte)0xC5;
}
}

}

+ 85
- 0
src/java/org/apache/fop/afp/goca/GraphicsFullArc.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.util.BinaryUtils;

/**
* A GOCA graphics arc (circle/ellipse)
*/
public class GraphicsFullArc extends AbstractGraphicsCoord {

/** the integer portion of the multiplier */
private final int mh;

/** the fractional portion of the multiplier */
private final int mhr;

/**
* Constructor
*
* @param x the x coordinate of the center of the circle/ellipse
* @param y the y coordinate of the center of the circle/ellipse
* @param mh the integer portion of the multiplier
* @param mhr the fractional portion of the multiplier
*/
public GraphicsFullArc(int x, int y, int mh, int mhr) {
super(x, y);
this.mh = mh;
this.mhr = mhr;
}

/** {@inheritDoc} */
public int getDataLength() {
return 8;
}

/** {@inheritDoc} */
byte getOrderCode() {
return (byte)0xC7;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = getData();

// integer portion of multiplier
data[6] = BinaryUtils.convert(mh, 1)[0];

// fractional portion of multiplier
data[7] = BinaryUtils.convert(mhr, 1)[0];

os.write(data);
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsFullArc{"
+ ", centerx=" + coords[0]
+ ", centery=" + coords[1]
+ ", mh=" + mh
+ ", mhr=" + mhr
+ "}";
}

}

+ 120
- 0
src/java/org/apache/fop/afp/goca/GraphicsImage.java View File

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

/* $Id$ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.util.BinaryUtils;

/**
* A GOCA Image
*/
public class GraphicsImage extends AbstractGraphicsDrawingOrder {

/** the maximum image data length */
public static final short MAX_DATA_LEN = 255;

/** x coordinate */
private final int x;

/** y coordinate */
private final int y;

/** width */
private final int width;

/** height */
private final int height;

/** image data */
private final byte[] imageData;

/**
* Main constructor
*
* @param x the x coordinate of the image
* @param y the y coordinate of the image
* @param width the image width
* @param height the image height
* @param imageData the image data
*/
public GraphicsImage(int x, int y, int width, int height, byte[] imageData) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.imageData = imageData;
}

/** {@inheritDoc} */
public int getDataLength() {
//TODO:
return 0;
}

byte getOrderCode() {
return (byte)0xD1;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] xcoord = BinaryUtils.convert(x, 2);
byte[] ycoord = BinaryUtils.convert(y, 2);
byte[] w = BinaryUtils.convert(width, 2);
byte[] h = BinaryUtils.convert(height, 2);
byte[] startData = new byte[] {
getOrderCode(), // GBIMG order code
(byte) 0x0A, // LENGTH
xcoord[0],
xcoord[1],
ycoord[0],
ycoord[1],
0x00, // FORMAT
0x00, // RES
w[0], // WIDTH
w[1], //
h[0], // HEIGHT
h[1] //
};
os.write(startData);

byte[] dataHeader = new byte[] {
(byte) 0x92 // GIMD
};
final int lengthOffset = 1;
writeChunksToStream(imageData, dataHeader, lengthOffset, MAX_DATA_LEN, os);

byte[] endData = new byte[] {
(byte) 0x93, // GEIMG order code
0x00 // LENGTH
};
os.write(endData);
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsImage{x=" + x
+ ", y=" + y
+ ", width=" + width
+ ", height=" + height
+ "}";
}
}

+ 56
- 0
src/java/org/apache/fop/afp/goca/GraphicsLine.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

/**
* A GOCA graphics straight line drawn from the
* given absolute position
*/
public class GraphicsLine extends AbstractGraphicsCoord {

/**
* Constructor
*
* @param coords the x/y coordinates for this object
*
* @param relative is this a relative drawing order
*/
public GraphicsLine(int[] coords, boolean relative) {
super(coords, relative);
}

/** {@inheritDoc} */
byte getOrderCode() {
if (isRelative()) {
return (byte)0x81;
} else {
return (byte)0xC1;
}
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = getData();
os.write(data);
}
}

+ 51
- 0
src/java/org/apache/fop/afp/goca/GraphicsSetArcParameters.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

/**
* Sets the arc parameters for a GOCA graphics arc (circle/ellipse)
*/
public class GraphicsSetArcParameters extends AbstractGraphicsCoord {

/**
* Constructor
*
* @param xmaj x coordinate of the major axis point
* @param ymin y coordinate of the minor axis point
* @param xmin x coordinate of the minor axis point
* @param ymaj y coordinate of the major axis point
*/
public GraphicsSetArcParameters(int xmaj, int ymin, int xmin, int ymaj) {
super(xmaj, ymin, xmin, ymaj);
}

/** {@inheritDoc} */
protected byte getOrderCode() {
return 0x22;
}

/** {@inheritDoc} */
public String toString() {
return getName() + "{xmaj=" + coords[0]
+ ",ymin=" + coords[1]
+ ",xmin=" + coords[2]
+ ",ymaj=" + coords[3] + "}";
}
}

+ 66
- 0
src/java/org/apache/fop/afp/goca/GraphicsSetCharacterSet.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.util.BinaryUtils;

/**
* Sets the current character set (font) to be used for following graphics strings
*/
public class GraphicsSetCharacterSet extends AbstractGraphicsDrawingOrder {

/** font character set reference */
private final int fontReference;

/**
* @param fontReference character set font reference
*/
public GraphicsSetCharacterSet(int fontReference) {
this.fontReference = fontReference;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
getOrderCode(), // GSCS order code
BinaryUtils.convert(fontReference)[0]
};
os.write(data);
}

/** {@inheritDoc} */
public int getDataLength() {
return 2;
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsSetCharacterSet(" + fontReference + ")";
}

/** {@inheritDoc} */
byte getOrderCode() {
return 0x38;
}

}

+ 40
- 0
src/java/org/apache/fop/afp/goca/GraphicsSetCurrentPosition.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

/**
* Sets the current painting position of the graphics object
*/
public class GraphicsSetCurrentPosition extends AbstractGraphicsCoord {

/**
* Constructor
*
* @param coords the x/y coordinates for this object
*/
public GraphicsSetCurrentPosition(int[] coords) {
super(coords);
}

/** {@inheritDoc} */
protected byte getOrderCode() {
return (byte)0x21;
}
}

+ 97
- 0
src/java/org/apache/fop/afp/goca/GraphicsSetLineType.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

/**
* Sets the value of the current line type attribute when stroking GOCA shapes (structured fields)
*/
public class GraphicsSetLineType extends AbstractGraphicsDrawingOrder {

/** the default line type */
public static final byte DEFAULT = 0x00; // normally SOLID

/** the default line type */
public static final byte DOTTED = 0x01;

/** short dashed line type */
public static final byte SHORT_DASHED = 0x02;

/** dashed dotted line type */
public static final byte DASH_DOT = 0x03;

/** double dotted line type */
public static final byte DOUBLE_DOTTED = 0x04;

/** long dashed line type */
public static final byte LONG_DASHED = 0x05;

/** dash double dotted line type */
public static final byte DASH_DOUBLE_DOTTED = 0x06;

/** solid line type */
public static final byte SOLID = 0x07;

/** invisible line type */
public static final byte INVISIBLE = 0x08;

/** line type */
private byte type = DEFAULT;

/**
* Main constructor
*
* @param type line type
*/
public GraphicsSetLineType(byte type) {
this.type = type;
}

/** {@inheritDoc} */
public int getDataLength() {
return 2;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
getOrderCode(), // GSLW order code
type // line type
};
os.write(data);
}

private static final String[] TYPES = {
"default (solid)", "dotted", "short dashed", "dash dotted", "double dotted",
"long dashed", "dash double dotted", "solid", "invisible"
};

/** {@inheritDoc} */
public String toString() {
return "GraphicsSetLineType{type=" + TYPES[type] + "}";
}

/** {@inheritDoc} */
byte getOrderCode() {
return 0x18;
}
}

+ 65
- 0
src/java/org/apache/fop/afp/goca/GraphicsSetLineWidth.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

/**
* Sets the line width to use when stroking GOCA shapes (structured fields)
*/
public class GraphicsSetLineWidth extends AbstractGraphicsDrawingOrder {

/** line width multiplier */
private int multiplier = 1;

/**
* Main constructor
*
* @param multiplier the line width multiplier
*/
public GraphicsSetLineWidth(int multiplier) {
this.multiplier = multiplier;
}

/** {@inheritDoc} */
public int getDataLength() {
return 2;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
getOrderCode(), // GSLW order code
(byte)multiplier // MH (line-width)
};
os.write(data);
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsSetLineWidth{multiplier=" + multiplier + "}";
}

/** {@inheritDoc} */
byte getOrderCode() {
return 0x19;
}
}

+ 69
- 0
src/java/org/apache/fop/afp/goca/GraphicsSetMix.java View File

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

/* $Id$ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

/**
* Sets the foreground mix mode.
*/
public class GraphicsSetMix extends AbstractGraphicsDrawingOrder {

public static final byte MODE_DEFAULT = 0x00;
public static final byte MODE_OVERPAINT = 0x02;

/** the mix mode value */
private final byte mode;

/**
* Main constructor
*
* @param mode the mix mode value
*/
public GraphicsSetMix(byte mode) {
this.mode = mode;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
0x0C, // GSMX order code
mode // MODE (mix mode value)
};
os.write(data);
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsSetMix{mode=" + mode + "}";
}

/** {@inheritDoc} */
byte getOrderCode() {
return 0x0C;
}

/** {@inheritDoc} */
public int getDataLength() {
return 2;
}

}

+ 117
- 0
src/java/org/apache/fop/afp/goca/GraphicsSetPatternSymbol.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.io.IOException;
import java.io.OutputStream;

/**
* Sets the pattern symbol to use when filling following GOCA structured fields
*/
public class GraphicsSetPatternSymbol extends AbstractGraphicsDrawingOrder {

/** dotted density 1 */
public static final byte DOTTED_DENSITY_1 = 0x01;

/** dotted density 2 */
public static final byte DOTTED_DENSITY_2 = 0x02;

/** dotted density 3 */
public static final byte DOTTED_DENSITY_3 = 0x03;

/** dotted density 4 */
public static final byte DOTTED_DENSITY_4 = 0x04;

/** dotted density 5 */
public static final byte DOTTED_DENSITY_5 = 0x05;

/** dotted density 6 */
public static final byte DOTTED_DENSITY_6 = 0x06;

/** dotted density 7 */
public static final byte DOTTED_DENSITY_7 = 0x07;

/** dotted density 8 */
public static final byte DOTTED_DENSITY_8 = 0x08;

/** dotted density 9 */
public static final byte VERTICAL_LINES = 0x09;

/** horizontal lines */
public static final byte HORIZONTAL_LINES = 0x0A;

/** diagonal lines, bottom left to top right 1 */
public static final byte DIAGONAL_LINES_BLTR_1 = 0x0B;

/** diagonal lines, bottom left to top right 2 */
public static final byte DIAGONAL_LINES_BLTR_2 = 0x0C;

/** diagonal lines, top left to bottom right 1 */
public static final byte DIAGONAL_LINES_TLBR_1 = 0x0D;

/** diagonal lines, top left to bottom right 2 */
public static final byte DIAGONAL_LINES_TLBR_2 = 0x0E;

/** no fill */
public static final byte NO_FILL = 0x0F;

/** solid fill */
public static final byte SOLID_FILL = 0x10;

/** blank (same as no fill) */
public static final byte BLANK = 0x40; // processed same as NO_FILL

/** the graphics pattern symbol to use */
private final byte pattern;

/**
* Main constructor
*
* @param symb the pattern symbol to use
*/
public GraphicsSetPatternSymbol(byte pattern) {
this.pattern = pattern;
}

/** {@inheritDoc} */
public int getDataLength() {
return 2;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
getOrderCode(), // GSPT order code
pattern
};
os.write(data);
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsSetPatternSymbol(fill="
+ (pattern == SOLID_FILL ? true : false) + ")";
}

/** {@inheritDoc} */
byte getOrderCode() {
return 0x28;
}
}

+ 104
- 0
src/java/org/apache/fop/afp/goca/GraphicsSetProcessColor.java View File

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

/* $Id: $ */

package org.apache.fop.afp.goca;

import java.awt.Color;
import java.awt.color.ColorSpace;
import java.io.IOException;
import java.io.OutputStream;

/**
* Sets the current processing color for the following GOCA structured fields
*/
public class GraphicsSetProcessColor extends AbstractGraphicsDrawingOrder {

private final Color color;

private final float[] colorComponents;

/**
* Main constructor
*
* @param color the color to set
*/
public GraphicsSetProcessColor(Color color) {
this.color = color;
this.colorComponents = color.getColorComponents(null);
}

/** {@inheritDoc} */
public int getDataLength() {
return 12 + colorComponents.length;
}

/** {@inheritDoc} */
byte getOrderCode() {
return (byte)0xB2;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {

// COLSPCE
byte colspace;
int colSpaceType = color.getColorSpace().getType();
if (colSpaceType == ColorSpace.TYPE_CMYK) {
colspace = 0x04;
} else if (colSpaceType == ColorSpace.TYPE_RGB) {
colspace = 0x01;
} else {
log.error("unsupported colorspace " + colSpaceType);
colspace = 0x01;
}

// COLSIZE(S)
byte[] colsizes = new byte[] {0x00, 0x00, 0x00, 0x00};
for (int i = 0; i < colorComponents.length; i++) {
colsizes[i] = (byte)8;
}

int len = getDataLength();
byte[] data = new byte[len];
data[0] = getOrderCode(); // GSPCOL order code
data[1] = (byte)(len - 2); // LEN
data[2] = 0x00; // reserved; must be zero
data[3] = colspace; // COLSPCE
data[4] = 0x00; // reserved; must be zero
data[5] = 0x00; // reserved; must be zero
data[6] = 0x00; // reserved; must be zero
data[7] = 0x00; // reserved; must be zero
data[8] = colsizes[0]; // COLSIZE(S)
data[9] = colsizes[1];
data[10] = colsizes[2];
data[11] = colsizes[3];

// COLVALUE(S)
for (int i = 0; i < colorComponents.length; i++) {
data[i + 12] = (byte)(colorComponents[i] * 255);
}

os.write(data);
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsSetProcessColor(col=" + color + ")";
}
}

+ 23
- 0
src/java/org/apache/fop/afp/goca/package.html View File

@@ -0,0 +1,23 @@
<!--
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.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
<HTML>
<TITLE>org.apache.fop.afp.fonts Package</TITLE>
<BODY>
<P>Contains a collection of AFP font related classes.</P>
</BODY>
</HTML>

src/java/org/apache/fop/render/afp/modca/ImageCellPosition.java → src/java/org/apache/fop/afp/ioca/ImageCellPosition.java View File

@@ -17,11 +17,13 @@

/* $Id$ */

package org.apache.fop.render.afp.modca;
package org.apache.fop.afp.ioca;

import java.io.IOException;
import java.io.OutputStream;
import org.apache.fop.render.afp.tools.BinaryUtils;

import org.apache.fop.afp.modca.AbstractAFPObject;
import org.apache.fop.afp.util.BinaryUtils;

/**
* The IM Image Cell Position structured field specifies the placement,
@@ -29,38 +31,27 @@ import org.apache.fop.render.afp.tools.BinaryUtils;
*/
public class ImageCellPosition extends AbstractAFPObject {

/**
* Offset of image cell in X direction
*/
/** offset of image cell in X direction */
private int xOffset = 0;

/**
* Offset of image cell in Y direction
*/
/** offset of image cell in Y direction */
private int yOffset = 0;

/**
* Size of image cell in X direction
*/
private byte[] xSize = new byte[] {(byte)0xFF, (byte)0xFF};
/** size of image cell in X direction */
private final byte[] xSize = new byte[] {(byte)0xFF, (byte)0xFF};

/**
* Size of image cell in Y direction
*/
private byte[] ySize = new byte[] {(byte)0xFF, (byte)0xFF};
/** size of image cell in Y direction */
private final byte[] ySize = new byte[] {(byte)0xFF, (byte)0xFF};

/**
* Size of fill rectangle in X direction
*/
private byte[] xFillSize = new byte[] {(byte)0xFF, (byte)0xFF};
/** size of fill rectangle in X direction */
private final byte[] xFillSize = new byte[] {(byte)0xFF, (byte)0xFF};

/**
* Size of fill rectangle in Y direction
*/
private byte[] yFillSize = new byte[] {(byte)0xFF, (byte)0xFF};
/** size of fill rectangle in Y direction */
private final byte[] yFillSize = new byte[] {(byte)0xFF, (byte)0xFF};

/**
* Constructor for the ImageCellPosition
* Main Constructor
*
* @param x The offset of image cell in X direction
* @param y The offset of image cell in Y direction
*/
@@ -69,26 +60,14 @@ public class ImageCellPosition extends AbstractAFPObject {
yOffset = y;
}

/**
* Accessor method to write the AFP datastream for the Image Cell Position
* @param os The stream to write to
* @throws java.io.IOException if an I/O exception occurred
*/
public void writeDataStream(OutputStream os) throws IOException {
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[21];
copySF(data, Type.POSITION, Category.IM_IMAGE);

data[0] = 0x5A;

data[1] = 0x00;
data[1] = 0x00; // length
data[2] = 0x14;

data[3] = (byte) 0xD3;
data[4] = (byte) 0xAC;
data[5] = (byte) 0x7B;
data[6] = 0x00;
data[7] = 0x00;
data[8] = 0x00;

/**
* Specifies the offset along the Xp direction, in image points,
* of this image cell from the IM image object area origin.
@@ -125,6 +104,7 @@ public class ImageCellPosition extends AbstractAFPObject {
* of this image cell. A value of X'FFFF' indicates that the
* default extent specified in bytes 28 and 29 of the Image
* Input Descriptor (IID) is to be used.
*
* @param xcSize The size to set.
*/
public void setXSize(int xcSize) {
@@ -141,6 +121,7 @@ public class ImageCellPosition extends AbstractAFPObject {
* be used as the fill rectangle X-extent. The fill rectangle is
* filled in the X direction by repeating the image cell in the
* X direction. The image cell can be truncated to fit the rectangle.
*
* @param size The size to set.
*/
public void setXFillSize(int size) {
@@ -154,6 +135,7 @@ public class ImageCellPosition extends AbstractAFPObject {
* of this image cell. A value of X'FFFF' indicates that the
* default extent specified in bytes 30 and 31 of the Image
* Input Descriptor (IID) is to be used.
*
* @param size The size to set.
*/
public void setYSize(int size) {
@@ -170,6 +152,7 @@ public class ImageCellPosition extends AbstractAFPObject {
* be used as the fill rectangle Y-extent. The fill rectangle is
* filled in the Y direction by repeating the image cell in the
* Y direction. The image cell can be truncated to fit the rectangle.
*
* @param size The size to set.
*/
public void setYFillSize(int size) {

+ 267
- 0
src/java/org/apache/fop/afp/ioca/ImageContent.java View File

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

/* $Id$ */

package org.apache.fop.afp.ioca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.modca.AbstractStructuredObject;

/**
* An IOCA Image Content
*/
public class ImageContent extends AbstractStructuredObject {

/**
* The CCITT T.4 Group 3 Coding Standard (G3 MH-Modified Huffman) is a
* compression method standardized by the International Telegraph and
* Telephone Consultative Committee (CCITT) for facsimile. It enables
* one-dimensional compression.
*/
public static final byte COMPID_G3_MH = (byte)0x80;

/**
* The CCITT T.4 Group 3 Coding Option (G3 MR-Modified READ) is a
* compression method standardized by the International Telegraph and
* Telephone Consultative Committee (CCITT) for facsimile. It enables
* two-dimensional compression.
*/
public static final byte COMPID_G3_MR = (byte)0x81;

/**
* The CCITT T.6 Group 4 Coding Standard (G4 MMR-Modified Modified READ) is a
* compression method standardized by the International Telegraph and
* Telephone Consultative Committee (CCITT) for facsimile. It enables
* two-dimensional compression.
*/
public static final byte COMPID_G3_MMR = (byte)0x82;

/** the image size parameter */
private ImageSizeParameter imageSizeParameter = null;

/** the image encoding */
private byte encoding = (byte)0x03;

/** the image ide size */
private byte size = 1;

/** the image compression */
private byte compression = (byte)0xC0;

/** the image color model */
private byte colorModel = (byte)0x01;

/** the image data */
private byte[] data;

/**
* Main Constructor
*/
public ImageContent() {
}

/**
* Sets the image size parameter
*
* @param imageSizeParameter the image size parameter.
*/
public void setImageSizeParameter(ImageSizeParameter imageSizeParameter) {
this.imageSizeParameter = imageSizeParameter;
}

/**
* Sets the image encoding.
*
* @param enc The image encoding.
*/
public void setImageEncoding(byte enc) {
this.encoding = enc;
}

/**
* Sets the image compression.
*
* @param comp The image compression.
*/
public void setImageCompression(byte comp) {
this.compression = comp;
}

/**
* Sets the image IDE size.
*
* @param s The IDE size.
*/
public void setImageIDESize(byte s) {
this.size = s;
}

/**
* Sets the image IDE color model.
*
* @param color the IDE color model.
*/
public void setImageIDEColorModel(byte color) {
this.colorModel = color;
}

/**
* Set the image data (can be byte array or inputstream)
*
* @param imageData the image data
*/
public void setImageData(byte[] imageData) {
this.data = imageData;
}

private static final int MAX_DATA_LEN = 65535;

/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
if (imageSizeParameter != null) {
imageSizeParameter.writeToStream(os);
}

// TODO convert to triplet/parameter class
os.write(getImageEncodingParameter());

os.write(getImageIDESizeParameter());

os.write(getIDEStructureParameter());

os.write(getExternalAlgorithmParameter());

final byte[] dataHeader = new byte[] {
(byte)0xFE, // ID
(byte)0x92, // ID
0x00, // length
0x00 // length
};
final int lengthOffset = 2;

// Image Data
if (data != null) {
writeChunksToStream(data, dataHeader, lengthOffset, MAX_DATA_LEN, os);
}
}

/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
final byte[] startData = new byte[] {
(byte)0x91, // ID
0x01, // Length
(byte)0xff, // Object Type = IOCA Image Object
};
os.write(startData);
}

/** {@inheritDoc} */
protected void writeEnd(OutputStream os) throws IOException {
final byte[] endData = new byte[] {
(byte)0x93, // ID
0x00, // Length
};
os.write(endData);
}

/**
* Helper method to return the image encoding parameter.
*
* @return byte[] The data stream.
*/
private byte[] getImageEncodingParameter() {
final byte[] encodingData = new byte[] {
(byte)0x95, // ID
0x02, // Length
encoding,
0x01, // RECID
};
return encodingData;
}

/**
* Helper method to return the external algorithm parameter.
*
* @return byte[] The data stream.
*/
private byte[] getExternalAlgorithmParameter() {
if (encoding == (byte)0x83 && compression != 0) {
final byte[] extAlgData = new byte[] {
(byte)0x95, // ID
0x00, // Length
0x10, // ALGTYPE = Compression Algorithm
0x00, // Reserved
(byte)0x83, // COMPRID = JPEG
0x00, // Reserved
0x00, // Reserved
0x00, // Reserved
compression, // MARKER
0x00, // Reserved
0x00, // Reserved
0x00, // Reserved
};
extAlgData[1] = (byte)(extAlgData.length - 2);
return extAlgData;
}
return new byte[0];
}

/**
* Helper method to return the image encoding parameter.
*
* @return byte[] The data stream.
*/
private byte[] getImageIDESizeParameter() {
final byte[] ideSizeData = new byte[] {
(byte)0x96, // ID
0x01, // Length
size,
};
return ideSizeData;
}

/**
* Helper method to return the external algorithm parameter.
*
* @return byte[] The data stream.
*/
private byte[] getIDEStructureParameter() {
if (colorModel != 0 && size == 24) {
final byte bits = (byte)(size / 3);
final byte[] ideStructData = new byte[] {
(byte)0x9B, // ID
0x00, // Length
0x00, // FLAGS
0x00, // Reserved
colorModel, // COLOR MODEL
0x00, // Reserved
0x00, // Reserved
0x00, // Reserved
bits,
bits,
bits,
};
ideStructData[1] = (byte)(ideStructData.length - 2);
return ideStructData;
}
return new byte[0];
}

}

src/java/org/apache/fop/render/afp/modca/ImageInputDescriptor.java → src/java/org/apache/fop/afp/ioca/ImageInputDescriptor.java View File

@@ -17,11 +17,13 @@

/* $Id$ */

package org.apache.fop.render.afp.modca;
package org.apache.fop.afp.ioca;

import java.io.IOException;
import java.io.OutputStream;
import org.apache.fop.render.afp.tools.BinaryUtils;

import org.apache.fop.afp.modca.AbstractAFPObject;
import org.apache.fop.afp.util.BinaryUtils;

/**
* The IM Image Input Descriptor structured field contains the
@@ -30,30 +32,17 @@ import org.apache.fop.render.afp.tools.BinaryUtils;
*/
public class ImageInputDescriptor extends AbstractAFPObject {

/**
* The resolution of the raster image (default 240)
*/
/** the resolution of the raster image (default 240) */
private int resolution = 240;


/**
* Accessor method to write the AFP datastream for the Image Input Descriptor
* @param os The stream to write to
* @throws java.io.IOException if an I/O exception occurred
*/
public void writeDataStream(OutputStream os) throws IOException {
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {

byte[] data = new byte[45];
copySF(data, Type.DESCRIPTOR, Category.IM_IMAGE);

data[0] = 0x5A;
data[1] = 0x00;
data[1] = 0x00; // length
data[2] = 0x2C;
data[3] = (byte) 0xD3;
data[4] = (byte) 0xA6;
data[5] = (byte) 0x7B;
data[6] = 0x00;
data[7] = 0x00;
data[8] = 0x00;

// Constant data.
data[9] = 0x00;
@@ -131,12 +120,12 @@ public class ImageInputDescriptor extends AbstractAFPObject {
data[44] = (byte)0xFF;

os.write(data);

}

/**
* Sets the resolution information for the raster image
* the default value is a resolution of 240 dpi.
*
* @param resolution The resolution value
*/
public void setResolution(int resolution) {

src/java/org/apache/fop/render/afp/modca/ImageOutputControl.java → src/java/org/apache/fop/afp/ioca/ImageOutputControl.java View File

@@ -17,11 +17,13 @@

/* $Id$ */

package org.apache.fop.render.afp.modca;
package org.apache.fop.afp.ioca;

import java.io.IOException;
import java.io.OutputStream;
import org.apache.fop.render.afp.tools.BinaryUtils;

import org.apache.fop.afp.modca.AbstractAFPObject;
import org.apache.fop.afp.util.BinaryUtils;

/**
* The IM Image Output Control structured field specifies the position and
@@ -31,9 +33,7 @@ import org.apache.fop.render.afp.tools.BinaryUtils;
*/
public class ImageOutputControl extends AbstractAFPObject {

/**
* The orientation of the image
*/
/** the orientation of the image */
private int orientation = 0;

/**
@@ -48,9 +48,7 @@ public class ImageOutputControl extends AbstractAFPObject {
*/
private int yCoord = 0;

/**
* Map an image point to a single presentation device
*/
/** map an image point to a single presentation device */
private boolean singlePoint = true;

/**
@@ -67,18 +65,12 @@ public class ImageOutputControl extends AbstractAFPObject {
* The Y-axis offset.
*/
public ImageOutputControl(int x, int y) {

xCoord = x;
yCoord = y;

}

/**
* Accessor method to write the AFP datastream for the Image Output Control
* @param os The stream to write to
* @throws java.io.IOException if an I/O exception occured
*/
public void writeDataStream(OutputStream os) throws IOException {
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {

byte[] data = new byte[33];

@@ -170,7 +162,6 @@ public class ImageOutputControl extends AbstractAFPObject {
data[32] = (byte) 0xFF;

os.write(data);

}

/**

src/java/org/apache/fop/render/afp/modca/ImageRasterData.java → src/java/org/apache/fop/afp/ioca/ImageRasterData.java View File

@@ -17,11 +17,13 @@

/* $Id$ */

package org.apache.fop.render.afp.modca;
package org.apache.fop.afp.ioca;

import java.io.IOException;
import java.io.OutputStream;
import org.apache.fop.render.afp.tools.BinaryUtils;

import org.apache.fop.afp.modca.AbstractAFPObject;
import org.apache.fop.afp.util.BinaryUtils;

/**
* Contains the image points that define the IM image raster pattern.
@@ -45,43 +47,28 @@ import org.apache.fop.render.afp.tools.BinaryUtils;
*/
public class ImageRasterData extends AbstractAFPObject {

/**
* The image raster data
*/
private byte[] rasterData;
/** the image raster data */
private final byte[] rasterData;

/**
* Constructor for the image raster data object
*
* @param data The raster image data
*/
public ImageRasterData(byte[] data) {
this.rasterData = data;
}

/**
* Accessor method to write the AFP datastream for the Image Raster Data
* @param os The stream to write to
* @throws java.io.IOException if an I/O exception occurred
*/
public void writeDataStream(OutputStream os) throws IOException {

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[9];

data[0] = 0x5A;

copySF(data, Type.DATA, Category.IM_IMAGE);
// The size of the structured field
byte[] x = BinaryUtils.convert(rasterData.length + 8, 2);
data[1] = x[0];
data[2] = x[1];

data[3] = (byte) 0xD3;
data[4] = (byte) 0xEE;
data[5] = (byte) 0x7B;
data[6] = 0x00;
data[7] = 0x00;
data[8] = 0x00;

byte[] len = BinaryUtils.convert(rasterData.length + 8, 2);
data[1] = len[0];
data[2] = len[1];
os.write(data);

os.write(rasterData);
}
}

src/java/org/apache/fop/render/afp/modca/ImageRasterPattern.java → src/java/org/apache/fop/afp/ioca/ImageRasterPattern.java View File

@@ -17,7 +17,7 @@

/* $Id$ */

package org.apache.fop.render.afp.modca;
package org.apache.fop.afp.ioca;

/**
* Raster data is a grid of cells covering an area of interest.

+ 161
- 0
src/java/org/apache/fop/afp/ioca/ImageSegment.java View File

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

/* $Id$ */

package org.apache.fop.afp.ioca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.Factory;
import org.apache.fop.afp.modca.AbstractNamedAFPObject;

/**
* An Image Segment is represented by a set of self-defining fields, fields
* that describe their own contents. It starts with a Begin Segment, and
* ends with an End Segment.
*
* Between the Begin Segment and End Segment is the image information to
* be processed, called the Image Content.
*
* Only one Image Content can exist within a single IOCA Image Segment.
*/
public class ImageSegment extends AbstractNamedAFPObject {

/**
* The ImageContent for the image segment
*/
private ImageContent imageContent = null;

private final Factory factory;

/**
* Constructor for the image segment with the specified name,
* the name must be a fixed length of eight characters.
* @param factory the object factory
*
* @param name the name of the image.
*/
public ImageSegment(Factory factory, String name) {
super(name);
this.factory = factory;
}

private ImageContent getImageContent() {
if (imageContent == null) {
this.imageContent = factory.createImageContent();
}
return imageContent;
}

/**
* Sets the image size parameters resolution, hsize and vsize.
*
* @param hsize The horizontal size of the image.
* @param vsize The vertical size of the image.
* @param hresol The horizontal resolution of the image.
* @param vresol The vertical resolution of the image.
*/
public void setImageSize(int hsize, int vsize, int hresol, int vresol) {
ImageSizeParameter imageSizeParameter
= factory.createImageSizeParameter(hsize, vsize, hresol, vresol);
getImageContent().setImageSizeParameter(imageSizeParameter);
}

/**
* Sets the image encoding.
*
* @param encoding The image encoding.
*/
public void setEncoding(byte encoding) {
getImageContent().setImageEncoding(encoding);
}

/**
* Sets the image compression.
*
* @param compression The image compression.
*/
public void setCompression(byte compression) {
getImageContent().setImageCompression(compression);
}

/**
* Sets the image IDE size.
*
* @param size The IDE size.
*/
public void setIDESize(byte size) {
getImageContent().setImageIDESize(size);
}

/**
* Sets the image IDE color model.
*
* @param colorModel the IDE color model.
*/
public void setIDEColorModel(byte colorModel) {
getImageContent().setImageIDEColorModel(colorModel);
}

/**
* Set the data image data.
*
* @param data the image data
*/
public void setData(byte[] imageData) {
getImageContent().setImageData(imageData);
}

/** {@inheritDoc} */
public void writeContent(OutputStream os) throws IOException {
if (imageContent != null) {
imageContent.writeToStream(os);
}
}

private static final int NAME_LENGTH = 4;

/** {@inheritDoc} */
protected int getNameLength() {
return NAME_LENGTH;
}

/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
byte[] nameBytes = getNameBytes();
byte[] data = new byte[] {
0x70, // ID
0x04, // Length
nameBytes[0], // Name byte 1
nameBytes[1], // Name byte 2
nameBytes[2], // Name byte 3
nameBytes[3], // Name byte 4
};
os.write(data);
}

/** {@inheritDoc} */
protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[] {
0x71, // ID
0x00, // Length
};
os.write(data);
}
}

src/java/org/apache/fop/render/afp/modca/ImageSizeParameter.java → src/java/org/apache/fop/afp/ioca/ImageSizeParameter.java View File

@@ -17,43 +17,42 @@

/* $Id$ */

package org.apache.fop.render.afp.modca;
package org.apache.fop.afp.ioca;

import java.io.IOException;
import java.io.OutputStream;
import org.apache.fop.render.afp.tools.BinaryUtils;

import org.apache.fop.afp.modca.AbstractAFPObject;
import org.apache.fop.afp.util.BinaryUtils;

/**
* Describes the measurement characteristics of the image when it is created.
*/
public class ImageSizeParameter extends AbstractAFPObject {

private int hRes = 0;
private int vRes = 0;
private int hSize = 0;
private int vSize = 0;
private int hRes = 0;
private int vRes = 0;

/**
* Constructor for a ImageSizeParameter for the specified
* resolution, hsize and vsize.
* @param hresol The horizontal resolution of the image.
* @param vresol The vertical resolution of the image.
*
* @param hsize The horizontal size of the image.
* @param vsize The vertical size of the image.
* @param hresol The horizontal resolution of the image.
* @param vresol The vertical resolution of the image.
*/
public ImageSizeParameter(int hresol, int vresol, int hsize, int vsize) {
this.hRes = hresol;
this.vRes = vresol;
public ImageSizeParameter(int hsize, int vsize, int hresol, int vresol) {
this.hSize = hsize;
this.vSize = vsize;
this.hRes = hresol;
this.vRes = vresol;
}

/**
* Accessor method to write the AFP datastream for the Image Size Parameter
* @param os The stream to write to
* @throws java.io.IOException if an I/O exception occured
*/
public void writeDataStream(OutputStream os) throws IOException {
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
(byte)0x94, // ID = Image Size Parameter
0x09, // Length

+ 23
- 0
src/java/org/apache/fop/afp/ioca/package.html View File

@@ -0,0 +1,23 @@
<!--
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.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
<HTML>
<TITLE>org.apache.fop.afp.ioca Package</TITLE>
<BODY>
<P>Contains a collection of AFP Image Object Content Architecture (IOCA) structured objects.</P>
</BODY>
</HTML>

+ 321
- 0
src/java/org/apache/fop/afp/modca/AbstractAFPObject.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.Streamable;
import org.apache.fop.afp.util.BinaryUtils;

/**
* This is the base class for all data stream objects. Page objects are
* responsible for building and generating the binary datastream in an
* AFP format.
*/
public abstract class AbstractAFPObject implements Streamable {

/** Static logging instance */
protected static final Log log = LogFactory.getLog("org.apache.xmlgraphics.afp.modca");

/** the structured field class id */
protected static final byte SF_CLASS = (byte)0xD3;

private static final byte[] SF_HEADER = new byte[] {
0x5A, // Structured field identifier
0x00, // Length byte 1
0x10, // Length byte 2
SF_CLASS, // Structured field id byte 1
(byte) 0x00, // Structured field id byte 2
(byte) 0x00, // Structured field id byte 3
0x00, // Flags
0x00, // Reserved
0x00, // Reserved
};

/**
* Copies the template structured field data array to the given byte array
*
* @param data the structured field data byte array
* @param type the type code
* @param category the category code
*/
protected void copySF(byte[] data, byte type, byte category) {
copySF(data, SF_CLASS, type, category);
}

/**
* Copies the template structured field data array to the given byte array
*
* @param data the structured field data byte array
* @param clazz the class code
* @param type the type code
* @param category the category code
*/
protected static void copySF(byte[] data, byte clazz, byte type, byte category) {
System.arraycopy(SF_HEADER, 0, data, 0, SF_HEADER.length);
data[3] = clazz;
data[4] = type;
data[5] = category;
}

/**
* Writes a collection of Streamable to the AFP Datastream.
*
* @param objects a list of AFPObjects
* @param os The stream to write to
* @throws java.io.IOException an I/O exception of some sort has occurred.
*/
protected void writeObjects(Collection/*<Streamable>*/ objects, OutputStream os)
throws IOException {
if (objects != null && objects.size() > 0) {
Iterator it = objects.iterator();
while (it.hasNext()) {
Object object = it.next();
if (object instanceof Streamable) {
((Streamable)object).writeToStream(os);
it.remove(); // once written, immediately remove the object
}
}
}
}

/**
* Reads data chunks from an InputStream
* and then formats them with a structured header to a given OutputStream
*
* @param dataHeader the header data
* @param lengthOffset offset of length field in data chunk
* @param maxChunkLength the maximum chunk length
* @param inputStream the InputStream to read from
* @param outputStream the OutputStream to write to
* @throws IOException thrown if an I/O exception of some sort has occurred.
*/
protected static void copyChunks(byte[] dataHeader, int lengthOffset,
int maxChunkLength, InputStream inputStream, OutputStream outputStream)
throws IOException {
int headerLen = dataHeader.length - lengthOffset;
// length field is just before data so do not include in data length
if (headerLen == 2) {
headerLen = 0;
}
byte[] data = new byte[maxChunkLength];
int numBytesRead = 0;
while ((numBytesRead = inputStream.read(data, 0, maxChunkLength)) > 0) {
byte[] len = BinaryUtils.convert(headerLen + numBytesRead, 2);
dataHeader[lengthOffset] = len[0]; // Length byte 1
dataHeader[lengthOffset + 1] = len[1]; // Length byte 2
outputStream.write(dataHeader);
outputStream.write(data, 0, numBytesRead);
}
}

/**
* Writes data chunks to a given outputstream
*
* @param data the data byte array
* @param dataHeader the header data
* @param lengthOffset offset of length field in data chunk
* @param maxChunkLength the maximum chunk length
* @param os the outputstream to write to
* @throws IOException thrown if an I/O exception of some sort has occurred.
*/
protected static void writeChunksToStream(byte[] data, byte[] dataHeader,
int lengthOffset, int maxChunkLength, OutputStream os) throws IOException {
int dataLength = data.length;
int numFullChunks = dataLength / maxChunkLength;
int lastChunkLength = dataLength % maxChunkLength;

int headerLen = dataHeader.length - lengthOffset;
// length field is just before data so do not include in data length
if (headerLen == 2) {
headerLen = 0;
}

byte[] len;
int off = 0;
if (numFullChunks > 0) {
// write out full data chunks
len = BinaryUtils.convert(headerLen + maxChunkLength, 2);
dataHeader[lengthOffset] = len[0]; // Length byte 1
dataHeader[lengthOffset + 1] = len[1]; // Length byte 2
for (int i = 0; i < numFullChunks; i++, off += maxChunkLength) {
os.write(dataHeader);
os.write(data, off, maxChunkLength);
}
}

if (lastChunkLength > 0) {
// write last data chunk
len = BinaryUtils.convert(headerLen + lastChunkLength, 2);
dataHeader[lengthOffset] = len[0]; // Length byte 1
dataHeader[lengthOffset + 1] = len[1]; // Length byte 2
os.write(dataHeader);
os.write(data, off, lastChunkLength);
}
}

/** structured field type codes */
public interface Type {

/** Attribute */
byte ATTRIBUTE = (byte)0x0A;

/** Copy Count */
byte COPY_COUNT = (byte)0xA2;

/** Descriptor */
byte DESCRIPTOR = (byte)0xA6;

/** Control */
byte CONTROL = (byte)0xA7;

/** Begin */
byte BEGIN = (byte)0xA8;

/** End */
byte END = (byte)0xA9;

/** Map */
byte MAP = (byte)0xAB;

/** Position */
byte POSITION = (byte)0xAC;

/** Process */
byte PROCESS = (byte)0xAD;

/** Include */
byte INCLUDE = (byte)0xAF;

/** Table */
byte TABLE = (byte)0xB0;

/** Migration */
byte MIGRATION = (byte)0xB1;

/** Variable */
byte VARIABLE = (byte)0xB2;

/** Link */
byte LINK = (byte)0xB4;

/** Data */
byte DATA = (byte)0xEE;
}

/** structured field category codes */
public interface Category {

/** Page Segment */
byte PAGE_SEGMENT = (byte)0x5F;

/** Object Area */
byte OBJECT_AREA = (byte)0x6B;

/** Color Attribute Table */
byte COLOR_ATTRIBUTE_TABLE = (byte)0x77;

/** IM Image */
byte IM_IMAGE = (byte)0x7B;

/** Medium */
byte MEDIUM = (byte)0x88;

/** Coded Font */
byte CODED_FONT = (byte)0x8A;

/** Process Element */
byte PROCESS_ELEMENT = (byte)0x90;

/** Object Container */
byte OBJECT_CONTAINER = (byte)0x92;

/** Presentation Text */
byte PRESENTATION_TEXT = (byte)0x9B;

/** Index */
byte INDEX = (byte)0xA7;

/** Document */
byte DOCUMENT = (byte)0xA8;

/** Page Group */
byte PAGE_GROUP = (byte)0xAD;

/** Page */
byte PAGE = (byte)0xAF;

/** Graphics */
byte GRAPHICS = (byte)0xBB;

/** Data Resource */
byte DATA_RESOURCE = (byte)0xC3;

/** Document Environment Group (DEG) */
byte DOCUMENT_ENVIRONMENT_GROUP = (byte)0xC4;

/** Resource Group */
byte RESOURCE_GROUP = (byte)0xC6;

/** Object Environment Group (OEG) */
byte OBJECT_ENVIRONMENT_GROUP = (byte)0xC7;

/** Active Environment Group (AEG) */
byte ACTIVE_ENVIRONMENT_GROUP = (byte)0xC9;

/** Medium Map */
byte MEDIUM_MAP = (byte)0xCC;

/** Form Map */
byte FORM_MAP = (byte)0xCD;

/** Name Resource */
byte NAME_RESOURCE = (byte)0xCE;

/** Page Overlay */
byte PAGE_OVERLAY = (byte)0xD8;

/** Resource Environment Group (REG) */
byte RESOURCE_ENVIROMENT_GROUP = (byte)0xD9;

/** Overlay */
byte OVERLAY = (byte)0xDF;

/** Data Suppression */
byte DATA_SUPRESSION = (byte)0xEA;

/** Bar Code */
byte BARCODE = (byte)0xEB;

/** No Operation */
byte NO_OPERATION = (byte)0xEE;

/** Image */
byte IMAGE = (byte)0xFB;
}

}


+ 140
- 0
src/java/org/apache/fop/afp/modca/AbstractDataObject.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceLevel;
import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.Startable;

/**
* Abstract base class used by the ImageObject and GraphicsObject which both
* have define an ObjectEnvironmentGroup
*/
public abstract class AbstractDataObject extends AbstractNamedAFPObject implements Startable, Completable {

/** the object environment group */
protected ObjectEnvironmentGroup objectEnvironmentGroup = null;

/** the object factory */
protected final Factory factory;

/** the completion status of this object */
private boolean complete;

/** the starting status of this object */
private boolean started;

/**
* Named constructor
*
* @param factory the object factory
* @param name data object name
*/
public AbstractDataObject(Factory factory, String name) {
super(name);
this.factory = factory;
}

/**
* Sets the object view port (area position and size).
*
* @param dataObjectInfo
* the object area info
*/
public void setViewport(AFPDataObjectInfo dataObjectInfo) {
AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo();

// object area descriptor
int width = objectAreaInfo.getWidth();
int height = objectAreaInfo.getHeight();
int widthRes = objectAreaInfo.getWidthRes();
int heightRes = objectAreaInfo.getHeightRes();
ObjectAreaDescriptor objectAreaDescriptor
= factory.createObjectAreaDescriptor(width, height, widthRes, heightRes);
getObjectEnvironmentGroup().setObjectAreaDescriptor(objectAreaDescriptor);

// object area position
AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
AFPResourceLevel resourceLevel = resourceInfo.getLevel();
ObjectAreaPosition objectAreaPosition = null;
if (resourceLevel.isInline()) {
int x = objectAreaInfo.getX();
int y = objectAreaInfo.getY();
int rotation = objectAreaInfo.getRotation();
objectAreaPosition = factory.createObjectAreaPosition(x, y, rotation);
} else {
// positional values are specified in the oaOffset of the include object
objectAreaPosition = factory.createObjectAreaPosition(0, 0, 0);
}
getObjectEnvironmentGroup().setObjectAreaPosition(objectAreaPosition);
}

/**
* Gets the ObjectEnvironmentGroup
*
* @return the object environment group
*/
public ObjectEnvironmentGroup getObjectEnvironmentGroup() {
if (objectEnvironmentGroup == null) {
this.objectEnvironmentGroup = factory.createObjectEnvironmentGroup();
}
return objectEnvironmentGroup;
}

/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
setStarted(true);
}

/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
writeTriplets(os);
if (objectEnvironmentGroup != null) {
objectEnvironmentGroup.writeToStream(os);
}
}

/** {@inheritDoc} */
public void setStarted(boolean started) {
this.started = started;
}

/** {@inheritDoc} */
public boolean isStarted() {
return this.started;
}

/** {@inheritDoc} */
public void setComplete(boolean complete) {
this.complete = complete;
}

/** {@inheritDoc} */
public boolean isComplete() {
return this.complete;
}
}

src/java/org/apache/fop/render/afp/modca/AbstractDescriptor.java → src/java/org/apache/fop/afp/modca/AbstractDescriptor.java View File

@@ -17,33 +17,68 @@

/* $Id$ */

package org.apache.fop.render.afp.modca;
package org.apache.fop.afp.modca;

/**
* Base class for AFP descriptor objects
*/
public abstract class AbstractDescriptor extends AbstractAFPObject {
public abstract class AbstractDescriptor extends AbstractTripletStructuredObject {

/** width of this descriptor */
protected int width = 0;
/** height of this descriptor */
protected int height = 0;
/** width resolution of this descriptor */
protected int widthResolution = 0;
protected int widthRes = 0;
/** height resolution of this descriptor */
protected int heightResolution = 0;
protected int heightRes = 0;

/**
* Default constructor
*/
public AbstractDescriptor() {
}

/**
* Constructor a PresentationTextDescriptor for the specified
* width and height.
*
* @param width The width of the page.
* @param height The height of the page.
* @param widthResolution The width resolution of the page.
* @param heightResolution The height resolution of the page.
* @param widthRes The width resolution of the page.
* @param heightRes The height resolution of the page.
*/
public AbstractDescriptor(int width, int height, int widthResolution, int heightResolution) {
public AbstractDescriptor(int width, int height, int widthRes, int heightRes) {
this.width = width;
this.height = height;
this.widthResolution = widthResolution;
this.heightResolution = heightResolution;
this.widthRes = widthRes;
this.heightRes = heightRes;
}

/** {@inheritDoc} */
public String toString() {
return "width=" + width
+ ", height=" + height
+ ", widthRes=" + widthRes
+ ", heightRes=" + heightRes;
}

/**
* Returns the width
*
* @return the width
*/
public int getWidth() {
return this.width;
}

/**
* Returns the height
*
* @return the height
*/
public int getHeight() {
return this.height;
}

}

+ 101
- 0
src/java/org/apache/fop/afp/modca/AbstractEnvironmentGroup.java View File

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

/* $Id: $ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

/**
* A base class that encapsulates common features of
* ActiveEnvironmentGroup and ResourceEnvironmentGroup
*/
public abstract class AbstractEnvironmentGroup extends AbstractNamedAFPObject {

/**
* The collection of MapPageOverlay objects
*/
protected List mapPageOverlays = null;

/**
* Main constructor
*
* @param name the object name
*/
public AbstractEnvironmentGroup(String name) {
super(name);
}

private List getMapPageOverlays() {
if (mapPageOverlays == null) {
mapPageOverlays = new java.util.ArrayList();
}
return mapPageOverlays;
}

/**
* Actually creates the MPO object.
* Also creates the supporting object (an IPO)
*
* @param name the name of the overlay to be used
*/
public void createOverlay(String name) {
MapPageOverlay mpo = getCurrentMapPageOverlay();
if (mpo == null) {
mpo = new MapPageOverlay();
getMapPageOverlays().add(mpo);
}

try {
mpo.addOverlay(name);
} catch (MaximumSizeExceededException msee) {
mpo = new MapPageOverlay();
getMapPageOverlays().add(mpo);
try {
mpo.addOverlay(name);
} catch (MaximumSizeExceededException ex) {
// Should never happen (but log just in case)
log.error("createOverlay():: resulted in a MaximumSizeExceededException");
}
}
}

/**
* Getter method for the most recent MapPageOverlay added to the
* Active Environment Group (returns null if no MapPageOverlay exist)
*
* @return the most recent Map Coded Font
*/
private MapPageOverlay getCurrentMapPageOverlay() {
if (mapPageOverlays != null && mapPageOverlays.size() > 0) {
return (MapPageOverlay) mapPageOverlays.get(mapPageOverlays.size() - 1);
} else {
return null;
}
}

/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
super.writeContent(os);
if (mapPageOverlays != null) {
writeObjects(mapPageOverlays, os);
}
}
}

+ 122
- 0
src/java/org/apache/fop/afp/modca/AbstractNamedAFPObject.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.UnsupportedEncodingException;

import org.apache.fop.afp.AFPConstants;

/**
* This is the base class for all named data stream objects.
* A named data stream object has an 8 byte EBCIDIC name.
*/
public abstract class AbstractNamedAFPObject extends AbstractTripletStructuredObject {

private static final int DEFAULT_NAME_LENGTH = 8;

/**
* The actual name of the object
*/
protected String name = null;

/**
* Default constructor
*/
protected AbstractNamedAFPObject() {
}

/**
* Constructor for the ActiveEnvironmentGroup, this takes a
* name parameter which should be 8 characters long.
*
* @param name the object name
*/
protected AbstractNamedAFPObject(String name) {
this.name = name;
}

/**
* Returns the name length
*
* @return the name length
*/
protected int getNameLength() {
return DEFAULT_NAME_LENGTH;
}

/**
* Returns the name as a byte array in EBCIDIC encoding
*
* @return the name as a byte array in EBCIDIC encoding
*/
public byte[] getNameBytes() {
int afpNameLen = getNameLength();
int nameLen = name.length();
if (nameLen < afpNameLen) {
name = (name + " ").substring(0, afpNameLen);
} else if (name.length() > afpNameLen) {
String truncatedName = name.substring(nameLen - afpNameLen, nameLen);
log.warn("Constructor:: name '" + name + "'"
+ " truncated to " + afpNameLen + " chars"
+ " ('" + truncatedName + "')");
name = truncatedName;
}
byte[] nameBytes = null;
try {
nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
} catch (UnsupportedEncodingException usee) {
nameBytes = name.getBytes();
log.warn(
"Constructor:: UnsupportedEncodingException translating the name "
+ name);
}
return nameBytes;
}

/** {@inheritDoc} */
protected void copySF(byte[] data, byte type, byte category) {
super.copySF(data, type, category);
byte[] nameData = getNameBytes();
System.arraycopy(nameData, 0, data, 9, nameData.length);
}

/**
* Returns the name of this object
*
* @return the name of this object
*/
public String getName() {
return this.name;
}

/**
* Sets the name of this object
*
* @param name the object name
*/
public void setName(String name) {
this.name = name;
}

/** {@inheritDoc} */
public String toString() {
return getName();
}
}

+ 350
- 0
src/java/org/apache/fop/afp/modca/AbstractPageObject.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.fop.afp.AFPLineDataInfo;
import org.apache.fop.afp.AFPTextDataInfo;
import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.fonts.AFPFont;

/**
* Pages contain the data objects that comprise a presentation document. Each
* page has a set of data objects associated with it. Each page within a
* document is independent from any other page, and each must establish its own
* environment parameters.
*
* The page is the level in the document component hierarchy that is used for
* printing or displaying a document's content. The data objects contained in
* the page envelope in the data stream are presented when the page is
* presented. Each data object has layout information associated with it that
* directs the placement and orientation of the data on the page. In addition,
* each page contains layout information that specifies the measurement units,
* page width, and page depth.
*
* A page is initiated by a begin page structured field and terminated by an end
* page structured field. Structured fields that define objects and active
* environment groups or that specify attributes of the page may be encountered
* in page state.
*
*/
public abstract class AbstractPageObject extends AbstractNamedAFPObject implements Completable {

/** The active environment group for the page */
protected ActiveEnvironmentGroup activeEnvironmentGroup = null;

/** The current presentation text object */
private PresentationTextObject currentPresentationTextObject = null;

/** The list of tag logical elements */
protected List/*<TagLogicalElement>*/ tagLogicalElements = null;

/** The list of the include page segments */
protected List/*<IncludePageSegment>*/ includePageSegments = null;

/** The list of objects within this resource container */
protected List/*<AbstractStructuredAFPObject>*/ objects = new java.util.ArrayList();

/** The page width */
private int width;

/** The page height */
private int height;

/** The page rotation */
protected int rotation = 0;

/** The page state */
protected boolean complete = false;

/** The width resolution */
private int widthRes;

/** The height resolution */
private int heightRes;

/** the object factory */
protected final Factory factory;

/**
* Default constructor
*
* @param factory the object factory
*/
public AbstractPageObject(Factory factory) {
this.factory = factory;
}

/**
* Main constructor
*
* @param factory the object factory
* @param name the name of this page object
*/
public AbstractPageObject(Factory factory, String name) {
super(name);
this.factory = factory;
}

/**
* Construct a new page object for the specified name argument, the page
* name should be an 8 character identifier.
*
* @param factory
* the object factory.
* @param name
* the name of the page.
* @param width
* the width of the page.
* @param height
* the height of the page.
* @param rotation
* the rotation of the page.
* @param widthRes
* the width resolution of the page.
* @param heightRes
* the height resolution of the page.
*/
public AbstractPageObject(Factory factory,
String name, int width, int height, int rotation,
int widthRes, int heightRes) {
super(name);

this.factory = factory;
this.width = width;
this.height = height;
this.rotation = rotation;
this.widthRes = widthRes;
this.heightRes = heightRes;
}

/**
* Helper method to create a map coded font object on the current page, this
* method delegates the construction of the map coded font object to the
* active environment group on the page.
*
* @param fontReference
* the font number used as the resource identifier
* @param font
* the font
* @param size
* the point size of the font
*/
public void createFont(int fontReference, AFPFont font, int size) {
getActiveEnvironmentGroup().createFont(fontReference, font, size, 0);
}

/**
* Helper method to create a line on the current page, this method delegates
* to the presentation text object in order to construct the line.
*
* @param lineDataInfo the line data information.
*/
public void createLine(AFPLineDataInfo lineDataInfo) {
getPresentationTextObject().createLineData(lineDataInfo);
}

/**
* Helper method to create text on the current page, this method delegates
* to the presentation text object in order to construct the text.
*
* @param textDataInfo
* the afp text data
* @throws UnsupportedEncodingException thrown if character encoding is not supported
*/
public void createText(AFPTextDataInfo textDataInfo) throws UnsupportedEncodingException {
getPresentationTextObject().createTextData(textDataInfo);
}

/**
* Helper method to mark the end of the page. This should end the control
* sequence on the current presentation text object.
*/
public void endPage() {
if (currentPresentationTextObject != null) {
currentPresentationTextObject.endControlSequence();
}
setComplete(true);
}

/**
* Ends the presentation text object
*/
protected void endPresentationObject() {
if (currentPresentationTextObject != null) {
currentPresentationTextObject.endControlSequence();
currentPresentationTextObject = null;
}
}

/**
* Helper method to create a presentation text object
* on the current page and to return the object.
*
* @return the presentation text object
*/
private PresentationTextObject getPresentationTextObject() {
if (currentPresentationTextObject == null) {
PresentationTextObject presentationTextObject
= factory.createPresentationTextObject();
addObject(presentationTextObject);
this.currentPresentationTextObject = presentationTextObject;
}
return currentPresentationTextObject;
}

/**
* Creates a TagLogicalElement on the page.
*
* @param name
* the name of the tag
* @param value
* the value of the tag
*/
public void createTagLogicalElement(String name, String value) {
TagLogicalElement tle = new TagLogicalElement(name, value);
if (tagLogicalElements == null) {
tagLogicalElements = new java.util.ArrayList/*<TagLogicalElement>*/();
}
tagLogicalElements.add(tle);
}

/**
* Creates a NoOperation on the page.
*
* @param content the byte data
*/
public void createNoOperation(String content) {
addObject(new NoOperation(content));
}

/**
* Creates an IncludePageSegment on the current page.
*
* @param name
* the name of the page segment
* @param x
* the x coordinate of the page segment.
* @param y
* the y coordinate of the page segment.
*/
public void createIncludePageSegment(String name, int x, int y) {
IncludePageSegment ips = factory.createIncludePageSegment(name, x, y);
getIncludePageSegments().add(ips);
}

/**
* Returns the include page segments list
*
* @return the include page segments list
*/
private List getIncludePageSegments() {
if (this.includePageSegments == null) {
this.includePageSegments = new java.util.ArrayList/*<IncludePageSegment>*/();
}
return this.includePageSegments;
}

/**
* Returns the ActiveEnvironmentGroup associated with this page.
*
* @return the ActiveEnvironmentGroup object
*/
public ActiveEnvironmentGroup getActiveEnvironmentGroup() {
if (activeEnvironmentGroup == null) {
// every page object must have an ActiveEnvironmentGroup
this.activeEnvironmentGroup
= factory.createActiveEnvironmentGroup(width, height, widthRes, heightRes);

if (rotation != 0) {
switch (rotation) {
case 90:
activeEnvironmentGroup.setObjectAreaPosition(width, 0, rotation);
break;
case 180:
activeEnvironmentGroup.setObjectAreaPosition(width, height, rotation);
break;
case 270:
activeEnvironmentGroup.setObjectAreaPosition(0, height, rotation);
break;
default:
}
}
}
return activeEnvironmentGroup;
}

/**
* Returns the height of the page
*
* @return the height of the page
*/
public int getHeight() {
return height;
}

/**
* Returns the width of the page
*
* @return the width of the page
*/
public int getWidth() {
return width;
}

/**
* Returns the rotation of the page
*
* @return the rotation of the page
*/
public int getRotation() {
return rotation;
}

/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
super.writeContent(os);
writeObjects(this.objects, os);
}

/**
* Adds an AFP object reference to this page
*
* @param obj an AFP object
*/
public void addObject(Object obj) {
objects.add(obj);
}

/** {@inheritDoc} */
public void setComplete(boolean complete) {
this.complete = complete;
}

/** {@inheritDoc} */
public boolean isComplete() {
return this.complete;
}
}

+ 99
- 0
src/java/org/apache/fop/afp/modca/AbstractResourceEnvironmentGroupContainer.java View File

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

/* $Id: $ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.Factory;


/**
* An abstract class which encapsulates the common features of
* Document and PageGroup resource containers
*/
public abstract class AbstractResourceEnvironmentGroupContainer
extends AbstractResourceGroupContainer {

/**
* The resource environment group used to store complex resources
*/
protected ResourceEnvironmentGroup resourceEnvironmentGroup = null;

/**
* Main constructor
*
* @param factory the object factory
* @param name the name of this resource container
*/
public AbstractResourceEnvironmentGroupContainer(
Factory factory, String name) {
super(factory, name);
}

/**
* Adds a page to the resource container.
*
* @param page - the Page object
*/
public void addPage(PageObject page) {
addObject(page);
}

/**
* Adds a PageGroup to the resource container.
*
* @param pageGroup the PageGroup object
*/
public void addPageGroup(PageGroup pageGroup) {
addObject(pageGroup);
}

/**
* Creates an InvokeMediaMap on the page.
*
* @param name
* the name of the media map
*/
public void createInvokeMediumMap(String name) {
InvokeMediumMap invokeMediumMap = factory.createInvokeMediumMap(name);
addObject(invokeMediumMap);
}

/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
super.writeContent(os);
if (resourceEnvironmentGroup != null) {
resourceEnvironmentGroup.writeToStream(os);
}
}

/**
* Returns the resource environment group
*
* @return the resource environment group
*/
protected ResourceEnvironmentGroup getResourceEnvironmentGroup() {
if (resourceEnvironmentGroup == null) {
this.resourceEnvironmentGroup = factory.createResourceEnvironmentGroup();
}
return this.resourceEnvironmentGroup;
}
}

+ 168
- 0
src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java View File

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

/* $Id: $ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Iterator;

import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.Streamable;


/**
* An abstract container of resource objects
*/
public abstract class AbstractResourceGroupContainer extends AbstractPageObject
implements Streamable {

/** The container started state */
protected boolean started = false;

/** the resource group object */
protected ResourceGroup resourceGroup = null;

/**
* Default constructor
*
* @param factory the object factory
*/
public AbstractResourceGroupContainer(Factory factory) {
super(factory);
}

/**
* Named constructor
*
* @param factory the object factory
* @param name the name of this resource container
*/
public AbstractResourceGroupContainer(Factory factory, String name) {
super(factory, name);
}

/**
* Construct a new page object for the specified name argument, the page
* name should be an 8 character identifier.
*
* @param factory
* the object factory
* @param name
* the name of the page.
* @param width
* the width of the page.
* @param height
* the height of the page.
* @param rotation
* the rotation of the page.
* @param widthRes
* the width resolution of the page.
* @param heightRes
* the height resolution of the page.
*/
public AbstractResourceGroupContainer(Factory factory,
String name, int width, int height, int rotation, int widthRes, int heightRes) {
super(factory, name, width, height, rotation, widthRes, heightRes);
}

/**
* Return the number of resources in this container
*
* @return the number of resources in this container
*/
protected int getResourceCount() {
if (resourceGroup != null) {
return resourceGroup.getResourceCount();
}
return 0;
}

/**
* Returns true if this resource group container contains resources
*
* @return true if this resource group container contains resources
*/
protected boolean hasResources() {
return resourceGroup != null && resourceGroup.getResourceCount() > 0;
}

/**
* Returns the resource group in this resource group container
*
* @return the resource group in this resource group container
*/
public ResourceGroup getResourceGroup() {
if (resourceGroup == null) {
resourceGroup = factory.createResourceGroup();
}
return resourceGroup;
}

// /** {@inheritDoc} */
// protected void writeContent(OutputStream os) throws IOException {
// if (resourceGroup != null) {
// resourceGroup.writeToStream(os);
// }
// super.writeContent(os);
// }

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
if (!started) {
writeStart(os);
started = true;
}

writeContent(os);

if (complete) {
writeEnd(os);
}
}

/** {@inheritDoc} */
protected void writeObjects(Collection/*<AbstractAFPObject>*/ objects, OutputStream os)
throws IOException {
if (objects != null && objects.size() > 0) {
Iterator it = objects.iterator();
while (it.hasNext()) {
AbstractAFPObject ao = (AbstractAFPObject)it.next();
if (canWrite(ao)) {
ao.writeToStream(os);
it.remove();
} else {
break;
}
}
}
}

/**
* Returns true if this object can be written
*
* @param obj an AFP object
* @return true if this object can be written
*/
protected boolean canWrite(AbstractAFPObject obj) {
return obj instanceof AbstractPageObject && ((Completable)obj).isComplete();
}
}

+ 69
- 0
src/java/org/apache/fop/afp/modca/AbstractStructuredObject.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;

/**
* An abstract class encapsulating an MODCA structured object
*/
public abstract class AbstractStructuredObject extends AbstractAFPObject {

/**
* Default constructor
*/
protected AbstractStructuredObject() {
}

/**
* Helper method to write the start of the Object.
*
* @param os The stream to write to
* @throws IOException throws an I/O exception if one occurred
*/
protected void writeStart(OutputStream os) throws IOException {
}

/**
* Helper method to write the end of the Object.
*
* @param os The stream to write to
* @throws IOException an I/O exception if one occurred
*/
protected void writeEnd(OutputStream os) throws IOException {
}

/**
* Helper method to write the contents of the Object.
*
* @param os The stream to write to
* @throws IOException throws an I/O exception if one occurred
*/
protected void writeContent(OutputStream os) throws IOException {
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
writeStart(os);
writeContent(os);
writeEnd(os);
}
}

+ 181
- 0
src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.fop.afp.modca.Registry.ObjectType;
import org.apache.fop.afp.modca.triplets.AbstractTriplet;
import org.apache.fop.afp.modca.triplets.CommentTriplet;
import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet;

/**
* A MODCA structured object base class providing support for Triplets
*/
public class AbstractTripletStructuredObject extends AbstractStructuredObject {

/** list of object triplets */
protected List/*<AbstractTriplet>*/ triplets = new java.util.ArrayList/*<AbstractTriplet>*/();

/**
* Returns the triplet data length
*
* @return the triplet data length
*/
protected int getTripletDataLength() {
int dataLength = 0;
if (hasTriplets()) {
Iterator it = triplets.iterator();
while (it.hasNext()) {
AbstractTriplet triplet = (AbstractTriplet)it.next();
dataLength += triplet.getDataLength();
}
}
return dataLength;
}

/**
* Returns true when this structured field contains triplets
*
* @return true when this structured field contains triplets
*/
public boolean hasTriplets() {
return triplets.size() > 0;
}

/**
* Writes any triplet data
*
* @param os The stream to write to
* @throws IOException The stream to write to
*/
protected void writeTriplets(OutputStream os) throws IOException {
if (hasTriplets()) {
writeObjects(triplets, os);
triplets = null; // gc
}
}

/**
* Returns the first matching triplet found in the structured field triplet list
*
* @param tripletId the triplet identifier
*/
private AbstractTriplet getTriplet(byte tripletId) {
Iterator it = getTriplets().iterator();
while (it.hasNext()) {
AbstractTriplet triplet = (AbstractTriplet)it.next();
if (triplet.getId() == tripletId) {
return triplet;
}
}
return null;
}

/**
* Returns true of this structured field has the given triplet
*
* @param tripletId the triplet identifier
* @return true if the structured field has the given triplet
*/
public boolean hasTriplet(byte tripletId) {
return getTriplet(tripletId) != null;
}

/**
* Adds a triplet to this structured object
*
* @param triplet the triplet to add
*/
protected void addTriplet(AbstractTriplet triplet) {
triplets.add(triplet);
}

/**
* Adds a list of triplets to the triplets contained within this structured field
*
* @param tripletCollection a collection of triplets
*/
public void addTriplets(Collection/*<Triplet>*/ tripletCollection) {
if (tripletCollection != null) {
triplets.addAll(tripletCollection);
}
}

/** @return the triplet list pertaining to this resource */
protected List/*<Triplet>*/ getTriplets() {
return triplets;
}

/**
* Sets the fully qualified name of this resource
*
* @param fqnType the fully qualified name type of this resource
* @param fqnFormat the fully qualified name format of this resource
* @param fqName the fully qualified name of this resource
*/
public void setFullyQualifiedName(byte fqnType, byte fqnFormat, String fqName) {
addTriplet(new FullyQualifiedNameTriplet(fqnType, fqnFormat, fqName));
}

/** @return the fully qualified name of this triplet or null if it does not exist */
public String getFullyQualifiedName() {
FullyQualifiedNameTriplet fqNameTriplet
= (FullyQualifiedNameTriplet)getTriplet(AbstractTriplet.FULLY_QUALIFIED_NAME);
if (fqNameTriplet != null) {
return fqNameTriplet.getFullyQualifiedName();
}
log.warn(this + " has no fully qualified name");
return null;
}

/**
* Sets the objects classification
*
* @param objectClass the classification of the object
* @param objectType the MOD:CA registry object type entry for the given
* object/component type of the object
* @param dataInContainer whether the data resides in the container
* @param containerHasOEG whether the container has an object environment group
* @param dataInOCD whether the data resides in a object container data structured field
*/
public void setObjectClassification(
byte objectClass, ObjectType objectType,
boolean dataInContainer, boolean containerHasOEG, boolean dataInOCD) {
addTriplet(
new ObjectClassificationTriplet(
objectClass, objectType, dataInContainer, containerHasOEG, dataInOCD));
}

/**
* Sets a comment on this resource
*
* @param commentString a comment string
*/
public void setComment(String commentString) {
addTriplet(new CommentTriplet(AbstractTriplet.COMMENT, commentString));
}

}

+ 221
- 0
src/java/org/apache/fop/afp/modca/ActiveEnvironmentGroup.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import org.apache.fop.afp.Factory;
import org.apache.fop.afp.fonts.AFPFont;

/**
* An Active Environment Group (AEG) is associated with each page,
* and is contained in the page's begin-end envelope in the data stream.
* The active environment group contains layout and formatting information
* that defines the measurement units and size of the page, and may contain
* resource information.
*
* Any objects that are required for page presentation and that are to be
* treated as resource objects must be mapped with a map structured field
* in the AEG. The scope of an active environment group is the scope of its
* containing page or overlay.
*
*/
public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup {

/** The collection of MapCodedFont objects */
private final List/*<MapCodedFonts>*/ mapCodedFonts
= new java.util.ArrayList/*<MapCodedFonts>*/();

/** the collection of MapDataResource objects */
private final List mapDataResources = null;

/** the Object Area Descriptor for the active environment group */
private ObjectAreaDescriptor objectAreaDescriptor = null;

/** the Object Area Position for the active environment group */
private ObjectAreaPosition objectAreaPosition = null;

/** the PresentationTextDescriptor for the active environment group */
private PresentationTextDescriptor presentationTextDataDescriptor = null;

/** the PageDescriptor for the active environment group */
private PageDescriptor pageDescriptor = null;

/** the resource manager */
private final Factory factory;

/**
* Constructor for the ActiveEnvironmentGroup, this takes a
* name parameter which must be 8 characters long.
*
* @param factory the object factory
* @param name the active environment group name
* @param width the page width
* @param height the page height
* @param widthRes the page width resolution
* @param heightRes the page height resolution
*/
public ActiveEnvironmentGroup(Factory factory,
String name, int width, int height, int widthRes, int heightRes) {
super(name);

this.factory = factory;

// Create PageDescriptor
this.pageDescriptor
= factory.createPageDescriptor(width, height, widthRes, heightRes);

// Create ObjectAreaDescriptor
this.objectAreaDescriptor
= factory.createObjectAreaDescriptor(width, height, widthRes, heightRes);

// Create PresentationTextDataDescriptor
this.presentationTextDataDescriptor
= factory.createPresentationTextDataDescriptor(width, height,
widthRes, heightRes);
}

/**
* Set the position of the object area
*
* @param x the x offset
* @param y the y offset
* @param rotation the rotation
*/
public void setObjectAreaPosition(int x, int y, int rotation) {
this.objectAreaPosition = factory.createObjectAreaPosition(x, y, rotation);
}

/**
* Accessor method to obtain the PageDescriptor object of the
* active environment group.
*
* @return the page descriptor object
*/
public PageDescriptor getPageDescriptor() {
return pageDescriptor;
}

/**
* Accessor method to obtain the PresentationTextDataDescriptor object of
* the active environment group.
*
* @return the presentation text descriptor
*/
public PresentationTextDescriptor getPresentationTextDataDescriptor() {
return presentationTextDataDescriptor;
}

/** {@inheritDoc} */
public void writeContent(OutputStream os) throws IOException {
super.writeTriplets(os);

writeObjects(mapCodedFonts, os);
writeObjects(mapDataResources, os);
writeObjects(mapPageOverlays, os);

if (pageDescriptor != null) {
pageDescriptor.writeToStream(os);
}
if (objectAreaDescriptor != null && objectAreaPosition != null) {
objectAreaDescriptor.writeToStream(os);
objectAreaPosition.writeToStream(os);
}
if (presentationTextDataDescriptor != null) {
presentationTextDataDescriptor.writeToStream(os);
}
}

/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
copySF(data, Type.BEGIN, Category.ACTIVE_ENVIRONMENT_GROUP);
os.write(data);
}

/** {@inheritDoc} */
protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
copySF(data, Type.END, Category.ACTIVE_ENVIRONMENT_GROUP);
os.write(data);
}

/**
* Method to create a map coded font object
*
* @param fontRef the font number used as the resource identifier
* @param font the font
* @param size the point size of the font
* @param orientation the orientation of the font (e.g. 0, 90, 180, 270)
*/
public void createFont(int fontRef, AFPFont font, int size, int orientation) {
MapCodedFont mapCodedFont = getCurrentMapCodedFont();
if (mapCodedFont == null) {
mapCodedFont = factory.createMapCodedFont();
mapCodedFonts.add(mapCodedFont);
}

try {
mapCodedFont.addFont(fontRef, font, size, orientation);
} catch (MaximumSizeExceededException msee) {
mapCodedFont = factory.createMapCodedFont();
mapCodedFonts.add(mapCodedFont);

try {
mapCodedFont.addFont(fontRef, font, size, orientation);
} catch (MaximumSizeExceededException ex) {
// Should never happen (but log just in case)
log.error("createFont():: resulted in a MaximumSizeExceededException");
}
}
}

/**
* Getter method for the most recent MapCodedFont added to the
* Active Environment Group (returns null if no MapCodedFonts exist)
*
* @return the most recent Map Coded Font.
*/
private MapCodedFont getCurrentMapCodedFont() {
int size = mapCodedFonts.size();
if (size > 0) {
return (MapCodedFont)mapCodedFonts.get(size - 1);
} else {
return null;
}
}

// private List getMapDataResources() {
// if (mapDataResources == null) {
// mapDataResources = new java.util.ArrayList();
// }
// return mapDataResources;
//}

// /**
// * Method to create a map data resource object
// * @param dataObjectAccessor a data object accessor
// */
// protected void createMapDataResource(DataObjectAccessor dataObjectAccessor) {
// getMapDataResources().add(new MapDataResource(dataObjectAccessor));
// }
}

+ 84
- 0
src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.util.BinaryUtils;

/**
* Container data descriptor (to maintain compatibility with pre-year 2000 applications)
*/
public class ContainerDataDescriptor extends AbstractDescriptor {

/**
* Main constructor
*
* @param width the container data width
* @param height the container data height
* @param widthRes the container width resolution
* @param heightRes the container height resolution
*/
public ContainerDataDescriptor(int width, int height, int widthRes,
int heightRes) {
super(width, height, widthRes, heightRes);
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[21];
copySF(data, Type.DESCRIPTOR, Category.OBJECT_CONTAINER);

// SF length
byte[] len = BinaryUtils.convert(data.length - 1, 2);
data[1] = len[0];
data[2] = len[1];

// XocBase = 10 inches
data[9] = 0x00;

// YocBase = 10 inches
data[10] = 0x00;

// XocUnits
byte[] xdpi = BinaryUtils.convert(widthRes * 10, 2);
data[11] = xdpi[0];
data[12] = xdpi[1];

// YocUnits
byte[] ydpi = BinaryUtils.convert(heightRes * 10, 2);
data[13] = ydpi[0];
data[14] = ydpi[1];

// XocSize
byte[] xsize = BinaryUtils.convert(width, 3);
data[15] = xsize[0];
data[16] = xsize[1];
data[17] = xsize[2];

// YocSize
byte[] ysize = BinaryUtils.convert(height, 3);
data[18] = ysize[0];
data[19] = ysize[1];
data[20] = ysize[2];
}

}

+ 96
- 0
src/java/org/apache/fop/afp/modca/Document.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.Factory;

/**
* The document is the highest level of the MO:DCA data-stream document
* component hierarchy. Documents can be made up of pages, and the pages, which
* are at the intermediate level, can be made up of objects. Objects are at the
* lowest level, and can be bar codes, graphics, images, and presentation text.
*
* At each level of the hierarchy certain sets of MO:DCA data structures, called
* structured fields, are permissible. The document, pages and objects are
* bounded by structured fields that define their beginnings and their ends.
* These structured fields, called begin-end pairs, provide an envelope for the
* data-stream components. This feature enables a processor of the data stream
* that is not fully compliant with the architecture to bypass those objects
* that are beyond its scope, and to process the data stream to the best of its
* abilities.
*
* A presentation document is one that has been formatted and is intended for
* presentation, usually on a printer or display device. A data stream
* containing a presentation document should produce the same document content
* in the same format on different printers or display devices dependent,
* however, on the capabilities of each of the printers or display devices. A
* presentation document can reference resources that are to be included as part
* of the document to be presented.
*
*/
public final class Document extends AbstractResourceEnvironmentGroupContainer {

/**
* Constructor for the document object.
*
* @param factory
* the object factory
* @param name
* the name of the document
*/
public Document(Factory factory, String name) {
super(factory, name);
}

/**
* Method to mark the end of the page group.
*/
public void endDocument() {
complete = true;
}

/** {@inheritDoc} */
public boolean isComplete() {
return complete;
}

/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
copySF(data, Type.BEGIN, Category.DOCUMENT);
os.write(data);
}

/** {@inheritDoc} */
protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
copySF(data, Type.END, Category.DOCUMENT);
os.write(data);
}

/** {@inheritDoc} */
public String toString() {
return this.name;
}

}

+ 152
- 0
src/java/org/apache/fop/afp/modca/GraphicsDataDescriptor.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.util.BinaryUtils;

/**
* GOCA Graphics Data Descriptor
*/
public class GraphicsDataDescriptor extends AbstractDescriptor {

private final int xlwind;

private final int xrwind;

private final int ybwind;

private final int ytwind;

/**
* Main constructor
*
* @param xlwind
* the left edge of the graphics window
* @param xrwind
* the right edge of the graphics window
* @param ybwind
* the top edge of the graphics window
* @param ytwind
* the bottom edge of the graphics window
* @param widthRes
* the width resolution of the graphics window
* @param heightRes
* the height resolution of the graphics window
*/
public GraphicsDataDescriptor(int xlwind, int xrwind, int ybwind,
int ytwind, int widthRes, int heightRes) {
this.xlwind = xlwind;
this.xrwind = xrwind;
this.ybwind = ybwind;
this.ytwind = ytwind;
super.widthRes = widthRes;
super.heightRes = heightRes;
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] headerData = new byte[9];
copySF(headerData, Type.DESCRIPTOR, Category.GRAPHICS);

byte[] drawingOrderSubsetData = getDrawingOrderSubset();

byte[] windowSpecificationData = getWindowSpecification();

byte[] len = BinaryUtils.convert(headerData.length
+ drawingOrderSubsetData.length
+ windowSpecificationData.length - 1, 2);
headerData[1] = len[0];
headerData[2] = len[1];

os.write(headerData);
os.write(drawingOrderSubsetData);
os.write(windowSpecificationData);
}

/**
* Returns the drawing order subset data
*
* @return the drawing order subset data
*/
private byte[] getDrawingOrderSubset() {
final byte[] data = new byte[] {
// Drawing order subset
(byte) 0xF7,
7, // LENGTH
(byte) 0xB0, // drawing order subset
0x00, // reserved (must be zero)
0x00, // reserved (must be zero)
0x02, // SUBLEV
0x00, // VERSION 0
0x01, // LENGTH (of following field)
0x00 // GEOM
};
return data;
}

private static final int ABS = 2;
private static final int IMGRES = 8;

/**
* Returns the window specification data
*
* @return the window specification data
*/
private byte[] getWindowSpecification() {
byte[] xlcoord = BinaryUtils.convert(xlwind, 2);
byte[] xrcoord = BinaryUtils.convert(xrwind, 2);
byte[] xbcoord = BinaryUtils.convert(ybwind, 2);
byte[] ytcoord = BinaryUtils.convert(ytwind, 2);
byte[] xResol = BinaryUtils.convert(widthRes * 10, 2);
byte[] yResol = BinaryUtils.convert(heightRes * 10, 2);
byte[] imxyres = xResol;

// Window specification
final byte[] data = new byte[] {
(byte) 0xF6,
18, // LENGTH
(ABS + IMGRES), // FLAGS (ABS)
0x00, // reserved (must be zero)
0x00, // CFORMAT (coordinate format - 16bit high byte first signed)
0x00, // UBASE (unit base - ten inches)

xResol[0], // XRESOL
xResol[1],
yResol[0], // YRESOL
yResol[1],

imxyres[0], // IMXYRES (Number of image points per ten inches
imxyres[1], // in X and Y directions)

xlcoord[0], // XLWIND
xlcoord[1],
xrcoord[0], // XRWIND
xrcoord[1],
xbcoord[0], // YBWIND
xbcoord[1],
ytcoord[0], // YTWIND
ytcoord[1]
};
return data;
}
}

+ 385
- 0
src/java/org/apache/fop/afp/modca/GraphicsObject.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;

import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.StructuredData;
import org.apache.fop.afp.goca.GraphicsAreaBegin;
import org.apache.fop.afp.goca.GraphicsAreaEnd;
import org.apache.fop.afp.goca.GraphicsBox;
import org.apache.fop.afp.goca.GraphicsChainedSegment;
import org.apache.fop.afp.goca.GraphicsCharacterString;
import org.apache.fop.afp.goca.GraphicsData;
import org.apache.fop.afp.goca.GraphicsFillet;
import org.apache.fop.afp.goca.GraphicsFullArc;
import org.apache.fop.afp.goca.GraphicsImage;
import org.apache.fop.afp.goca.GraphicsLine;
import org.apache.fop.afp.goca.GraphicsSetArcParameters;
import org.apache.fop.afp.goca.GraphicsSetCharacterSet;
import org.apache.fop.afp.goca.GraphicsSetCurrentPosition;
import org.apache.fop.afp.goca.GraphicsSetLineType;
import org.apache.fop.afp.goca.GraphicsSetLineWidth;
import org.apache.fop.afp.goca.GraphicsSetPatternSymbol;
import org.apache.fop.afp.goca.GraphicsSetProcessColor;

/**
* Top-level GOCA graphics object.
*
* Acts as container and factory of all other graphic objects
*/
public class GraphicsObject extends AbstractDataObject {

/** the graphics data */
private GraphicsData currentData = null;

/** list of objects contained within this container */
protected List/*<GraphicsData>*/ objects
= new java.util.ArrayList/*<GraphicsData>*/();

/** the graphics state */
private final GraphicsState graphicsState = new GraphicsState();

/**
* Default constructor
*
* @param factory the object factory
* @param name the name of graphics object
*/
public GraphicsObject(Factory factory, String name) {
super(factory, name);
}

/** {@inheritDoc} */
public void setViewport(AFPDataObjectInfo dataObjectInfo) {
super.setViewport(dataObjectInfo);

AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo();
int width = objectAreaInfo.getWidth();
int height = objectAreaInfo.getHeight();
int widthRes = objectAreaInfo.getWidthRes();
int heightRes = objectAreaInfo.getHeightRes();
final int leftEdge = 0;
final int topEdge = 0;
GraphicsDataDescriptor graphicsDataDescriptor = factory.createGraphicsDataDescriptor(
leftEdge, width, topEdge, height, widthRes, heightRes);

getObjectEnvironmentGroup().setDataDescriptor(graphicsDataDescriptor);
}

/** {@inheritDoc} */
public void addObject(StructuredData object) {
if (currentData == null) {
newData();
} else if (currentData.getDataLength() + object.getDataLength()
>= GraphicsData.MAX_DATA_LEN) {
// graphics data full so transfer current incomplete segment to new data
GraphicsChainedSegment currentSegment
= (GraphicsChainedSegment)currentData.removeCurrentSegment();
currentSegment.setName(newData().createSegmentName());
currentData.addSegment(currentSegment);
}
currentData.addObject(object);
}

/**
* Gets the current graphics data, creating a new one if necessary
*
* @return the current graphics data
*/
private GraphicsData getData() {
if (this.currentData == null) {
return newData();
}
return this.currentData;
}

/**
* Creates a new graphics data
*
* @return a newly created graphics data
*/
private GraphicsData newData() {
if (currentData != null) {
currentData.setComplete(true);
}
this.currentData = factory.createGraphicsData();
objects.add(currentData);
return currentData;
}

/**
* Sets the current color
*
* @param color the active color to use
*/
public void setColor(Color color) {
if (!color.equals(graphicsState.color)) {
addObject(new GraphicsSetProcessColor(color));
graphicsState.color = color;
}
}

/**
* Sets the current position
*
* @param coords the x and y coordinates of the current position
*/
public void setCurrentPosition(int[] coords) {
addObject(new GraphicsSetCurrentPosition(coords));
}

/**
* Sets the line width
*
* @param lineWidth the line width multiplier
*/
public void setLineWidth(int lineWidth) {
if (lineWidth != graphicsState.lineWidth) {
addObject(new GraphicsSetLineWidth(lineWidth));
graphicsState.lineWidth = lineWidth;
}
}

/**
* Sets the line type
*
* @param lineType the line type
*/
public void setLineType(byte lineType) {
if (lineType != graphicsState.lineType) {
addObject(new GraphicsSetLineType(lineType));
graphicsState.lineType = lineType;
}
}

/**
* Sets whether the following shape is to be filled
*
* @param fill true if the following shape is to be filled
*/
public void setFill(boolean fill) {
setPatternSymbol(fill ?
GraphicsSetPatternSymbol.SOLID_FILL :
GraphicsSetPatternSymbol.NO_FILL);
}

/**
* Sets the fill pattern of the next shape
*
* @param the fill pattern of the next shape
*/
public void setPatternSymbol(byte patternSymbol) {
if (patternSymbol != graphicsState.patternSymbol) {
addObject(new GraphicsSetPatternSymbol(patternSymbol));
graphicsState.patternSymbol = patternSymbol;
}
}

/**
* Sets the character set to use
*
* @param characterSet the character set (font) reference
*/
public void setCharacterSet(int characterSet) {
if (characterSet != graphicsState.characterSet) {
addObject(new GraphicsSetCharacterSet(characterSet));
graphicsState.characterSet = characterSet;
}
}

/**
* Adds a line at the given x/y coordinates
*
* @param coords the x/y coordinates (can be a series)
*/
public void addLine(int[] coords) {
addLine(coords, false);
}

/**
* Adds a line at the given x/y coordinates
*
* @param coords the x/y coordinates (can be a series)
* @param relative relative true for a line at current position (relative to)
*/
public void addLine(int[] coords, boolean relative) {
addObject(new GraphicsLine(coords, relative));
}

/**
* Adds a box at the given coordinates
*
* @param coords the x/y coordinates
*/
public void addBox(int[] coords) {
addObject(new GraphicsBox(coords));
}

/**
* Adds a fillet (curve) at the given coordinates
*
* @param coords the x/y coordinates
*/
public void addFillet(int[] coords) {
addFillet(coords, false);
}

/**
* Adds a fillet (curve) at the given coordinates
*
* @param coords the x/y coordinates
* @param relative relative true for a fillet (curve) at current position (relative to)
*/
public void addFillet(int[] coords, boolean relative) {
addObject(new GraphicsFillet(coords, relative));
}

/**
* Sets the arc parameters
*
* @param xmaj the maximum value of the x coordinate
* @param ymin the minimum value of the y coordinate
* @param xmin the minimum value of the x coordinate
* @param ymaj the maximum value of the y coordinate
*/
public void setArcParams(int xmaj, int ymin, int xmin, int ymaj) {
addObject(new GraphicsSetArcParameters(xmaj, ymin, xmin, ymaj));
}

/**
* Adds a full arc
*
* @param x the x coordinate
* @param y the y coordinate
* @param mh the integer portion of the multiplier
* @param mhr the fractional portion of the multiplier
*/
public void addFullArc(int x, int y, int mh, int mhr) {
addObject(new GraphicsFullArc(x, y, mh, mhr));
}

/**
* Adds an image
*
* @param x the x coordinate
* @param y the y coordinate
* @param width the image width
* @param height the image height
* @param imgData the image data
*/
public void addImage(int x, int y, int width, int height, byte[] imgData) {
addObject(new GraphicsImage(x, y, width, height, imgData));
}

/**
* Adds a string
*
* @param str the string
* @param x the x coordinate
* @param y the y coordinate
*/
public void addString(String str, int x, int y) {
addObject(new GraphicsCharacterString(str, x, y));
}

/**
* Begins a graphics area (start of fill)
*/
public void beginArea() {
addObject(new GraphicsAreaBegin());
}

/**
* Ends a graphics area (end of fill)
*/
public void endArea() {
addObject(new GraphicsAreaEnd());
}

/** {@inheritDoc} */
public String toString() {
return "GraphicsObject: " + getName();
}

/**
* Creates a new graphics segment
*/
public void newSegment() {
getData().newSegment();
}

/** {@inheritDoc} */
public void setComplete(boolean complete) {
Iterator it = objects.iterator();
while (it.hasNext()) {
Completable completedObject = (Completable)it.next();
completedObject.setComplete(true);
}
super.setComplete(complete);
}

/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
super.writeStart(os);
byte[] data = new byte[17];
copySF(data, Type.BEGIN, Category.GRAPHICS);
os.write(data);
}

/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
super.writeContent(os);
writeObjects(objects, os);
}

/** {@inheritDoc} */
protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
copySF(data, Type.END, Category.GRAPHICS);
os.write(data);
}

/** the internal graphics state */
private class GraphicsState {
/** the current color */
private Color color;

/** the current line type */
private byte lineType;

/** the current line width */
private int lineWidth;

/** the current fill pattern */
private byte patternSymbol;

/** the current character set */
private int characterSet;
}
}

src/java/org/apache/fop/render/afp/modca/IMImageObject.java → src/java/org/apache/fop/afp/modca/IMImageObject.java View File

@@ -17,11 +17,16 @@

/* $Id$ */

package org.apache.fop.render.afp.modca;
package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.ioca.ImageCellPosition;
import org.apache.fop.afp.ioca.ImageInputDescriptor;
import org.apache.fop.afp.ioca.ImageOutputControl;
import org.apache.fop.afp.ioca.ImageRasterData;

/**
* An IM image data object specifies the contents of a raster image and
* its placement on a page, overlay, or page segment. An IM image can be
@@ -60,16 +65,16 @@ public class IMImageObject extends AbstractNamedAFPObject {
/**
* Constructor for the image object with the specified name,
* the name must be a fixed length of eight characters.
*
* @param name The name of the image.
*/
public IMImageObject(String name) {

super(name);

}

/**
* Sets the ImageOutputControl.
*
* @param imageOutputControl The imageOutputControl to set
*/
public void setImageOutputControl(ImageOutputControl imageOutputControl) {
@@ -78,6 +83,7 @@ public class IMImageObject extends AbstractNamedAFPObject {

/**
* Sets the ImageCellPosition.
*
* @param imageCellPosition The imageCellPosition to set
*/
public void setImageCellPosition(ImageCellPosition imageCellPosition) {
@@ -86,6 +92,7 @@ public class IMImageObject extends AbstractNamedAFPObject {

/**
* Sets the ImageInputDescriptor.
*
* @param imageInputDescriptor The imageInputDescriptor to set
*/
public void setImageInputDescriptor(ImageInputDescriptor imageInputDescriptor) {
@@ -94,98 +101,41 @@ public class IMImageObject extends AbstractNamedAFPObject {

/**
* Sets the ImageRastorData.
*
* @param imageRasterData The imageRasterData to set
*/
public void setImageRasterData(ImageRasterData imageRasterData) {
this.imageRasterData = imageRasterData;
}

/**
* Accessor method to write the AFP datastream for the IM Image Objetc
* @param os The stream to write to
* @throws java.io.IOException thrown if an I/O exception of some sort has occurred
*/
public void writeDataStream(OutputStream os)
throws IOException {

writeStart(os);

/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
super.writeContent(os);
if (imageOutputControl != null) {
imageOutputControl.writeDataStream(os);
imageOutputControl.writeToStream(os);
}

if (imageInputDescriptor != null) {
imageInputDescriptor.writeDataStream(os);
imageInputDescriptor.writeToStream(os);
}

if (imageCellPosition != null) {
imageCellPosition.writeDataStream(os);
imageCellPosition.writeToStream(os);
}

if (imageRasterData != null) {
imageRasterData.writeDataStream(os);
imageRasterData.writeToStream(os);
}

writeEnd(os);

}

/**
* Helper method to write the start of the IM Image Object.
* @param os The stream to write to
*/
private void writeStart(OutputStream os)
throws IOException {

/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];

data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
data[3] = (byte) 0xD3; // Structured field id byte 1
data[4] = (byte) 0xA8; // Structured field id byte 2
data[5] = (byte) 0x7B; // Structured field id byte 3
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved

for (int i = 0; i < nameBytes.length; i++) {

data[9 + i] = nameBytes[i];

}

copySF(data, Type.BEGIN, Category.IM_IMAGE);
os.write(data);

}

/**
* Helper method to write the end of the IM Image Object.
* @param os The stream to write to
*/
private void writeEnd(OutputStream os)
throws IOException {

/** {@inheritDoc} */
protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];

data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
data[3] = (byte) 0xD3; // Structured field id byte 1
data[4] = (byte) 0xA9; // Structured field id byte 2
data[5] = (byte) 0x7B; // Structured field id byte 3
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved

for (int i = 0; i < nameBytes.length; i++) {

data[9 + i] = nameBytes[i];

}

copySF(data, Type.END, Category.IM_IMAGE);
os.write(data);

}

}

+ 78
- 0
src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.util.BinaryUtils;

/**
* ImageDataDescriptor
*/
public class ImageDataDescriptor extends AbstractDescriptor {

/**
* Constructor for a ImageDataDescriptor for the specified
* resolution, width and height.
*
* @param width The width of the image.
* @param height The height of the height.
* @param widthRes The horizontal resolution of the image.
* @param heightRes The vertical resolution of the image.
*/
public ImageDataDescriptor(int width, int height, int widthRes, int heightRes) {
super(width, height, widthRes, heightRes);
}

/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[22];
copySF(data, Type.DESCRIPTOR, Category.IMAGE);

// SF length
byte[] len = BinaryUtils.convert(data.length - 1, 2);
data[1] = len[0];
data[2] = len[1];

byte[] x = BinaryUtils.convert(widthRes, 2);
data[10] = x[0];
data[11] = x[1];

byte[] y = BinaryUtils.convert(heightRes, 2);
data[12] = y[0];
data[13] = y[1];

byte[] w = BinaryUtils.convert(width, 2);
data[14] = w[0];
data[15] = w[1];

byte[] h = BinaryUtils.convert(height, 2);
data[16] = h[0];
data[17] = h[1];

data[18] = (byte)0xF7; // ID = Set IOCA Function Set
data[19] = 0x02; // Length
data[20] = 0x01; // Category = Function set identifier
data[21] = 0x0B; // FCNSET = IOCA FS 11

os.write(data);
}
}

+ 155
- 0
src/java/org/apache/fop/afp/modca/ImageObject.java View File

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

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPImageObjectInfo;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.ioca.ImageSegment;

/**
* An IOCA Image Data Object
*/
public class ImageObject extends AbstractDataObject {

private static final int MAX_DATA_LEN = 32759;

/** the image segment */
private ImageSegment imageSegment = null;

/**
* Constructor for the image object with the specified name,
* the name must be a fixed length of eight characters.
*
* @param name The name of the image.
* @param factory the resource manager
*/
public ImageObject(Factory factory, String name) {
super(factory, name);
}

private ImageSegment getImageSegment() {
if (imageSegment == null) {
this.imageSegment = factory.createImageSegment();
}
return imageSegment;
}

/** {@inheritDoc} */
public void setViewport(AFPDataObjectInfo dataObjectInfo) {
super.setViewport(dataObjectInfo);

AFPImageObjectInfo imageObjectInfo = (AFPImageObjectInfo)dataObjectInfo;
int dataWidth = imageObjectInfo.getDataWidth();
int dataHeight = imageObjectInfo.getDataHeight();

// AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo();
// int widthRes = objectAreaInfo.getWidthRes();
// int heightRes = objectAreaInfo.getHeightRes();

int dataWidthRes = imageObjectInfo.getDataWidthRes();
int dataHeightRes = imageObjectInfo.getDataWidthRes();
ImageDataDescriptor imageDataDescriptor
= factory.createImageDataDescriptor(dataWidth, dataHeight, dataWidthRes, dataHeightRes);
getObjectEnvironmentGroup().setDataDescriptor(imageDataDescriptor);

getImageSegment().setImageSize(dataWidth, dataHeight, dataWidthRes, dataHeightRes);
}

/**
* Sets the image encoding.
*
* @param encoding The image encoding.
*/
public void setEncoding(byte encoding) {
getImageSegment().setEncoding(encoding);
}

/**
* Sets the image compression.
*
* @param compression The image compression.
*/
public void setCompression(byte compression) {
getImageSegment().setCompression(compression);
}

/**
* Sets the image IDE size.
*
* @param size The IDE size.
*/
public void setIDESize(byte size) {
getImageSegment().setIDESize(size);
}

/**
* Sets the image IDE color model.
*
* @param colorModel the IDE color model.
*/
public void setIDEColorModel(byte colorModel) {
getImageSegment().setIDEColorModel(colorModel);
}

/**
* Set the data of the image.
*
* @param data the image data
*/
public void setData(byte[] imageData) {
getImageSegment().setData(imageData);
}

/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
copySF(data, Type.BEGIN, Category.IMAGE);
os.write(data);
}

/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
super.writeContent(os);

if (imageSegment != null) {
final byte[] dataHeader = new byte[9];
copySF(dataHeader, SF_CLASS, Type.DATA, Category.IMAGE);
final int lengthOffset = 1;

// TODO save memory!
ByteArrayOutputStream baos = new ByteArrayOutputStream();
imageSegment.writeToStream(baos);
byte[] data = baos.toByteArray();
writeChunksToStream(data, dataHeader, lengthOffset, MAX_DATA_LEN, os);
}
}

/** {@inheritDoc} */
protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
copySF(data, Type.END, Category.IMAGE);
os.write(data);
}
}

+ 0
- 0
src/java/org/apache/fop/afp/modca/IncludeObject.java View File


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

Loading…
Cancel
Save