diff options
352 files changed, 10664 insertions, 6460 deletions
@@ -563,14 +563,17 @@ list of possible build targets. <include name="org/apache/fop/apps/Fop.class"/> <include name="org/apache/fop/apps/FOPException.class"/> <include name="org/apache/fop/apps/io/**"/> + <include name="org/apache/fop/area/AreaTreeControl*"/> <include name="org/apache/fop/complexscripts/fonts/*.class"/> <include name="org/apache/fop/complexscripts/util/GlyphTester.class"/> + <include name="org/apache/fop/events/EventProducer.class"/> <include name="org/apache/fop/fo/Constants.class"/> <include name="org/apache/fop/fo/FOTreeBuilder.class"/> - <include name="org/apache/fop/area/AreaTreeControl*"/> + <include name="org/apache/fop/image/loader/batik/BatikImageFlavors*.class"/> <include name="org/apache/fop/svg/**"/> <include name="org/apache/fop/fonts/**"/> - <include name="org/apache/fop/image/loader/batik/BatikImageFlavors*.class"/> + <include name="org/apache/fop/render/shading/**"/> + <include name="org/apache/fop/traits/MinOptMax.class"/> <include name="org/apache/fop/util/CMYKColorSpace*.class"/> <include name="org/apache/fop/util/Color*.class"/> <include name="org/apache/fop/util/ASCII*.class"/> @@ -579,7 +582,7 @@ list of possible build targets. <include name="org/apache/fop/util/Finalizable.class"/> <include name="org/apache/fop/util/CharUtilities.class"/> <include name="org/apache/fop/util/DecimalFormatCache*.class"/> - <include name="org/apache/fop/render/shading/**"/> + <include name="org/apache/fop/util/ImageObject.class"/> </patternset> <!-- PDF transcoder --> <patternset> @@ -648,7 +651,8 @@ list of possible build targets. <include name="org/apache/xmlgraphics/java2d/**"/> <include name="org/apache/xmlgraphics/ps/**"/> <include name="org/apache/xmlgraphics/fonts/**"/> - <include name="org/apache/xmlgraphics/util/io/**"/> + <include name="org/apache/xmlgraphics/util/**"/> + <include name="org/apache/xmlgraphics/image/loader/**"/> </patternset> <fileset refid="transcoder-lib-files"/> </unjar> @@ -710,6 +714,7 @@ list of possible build targets. <include name="**/*.txt"/> <include name="**/*.afm"/> <include name="**/*.fo"/> + <include name="**/*.svg"/> </fileset> </copy> </target> @@ -1042,10 +1047,8 @@ NOTE: <!-- Checkstyle --> <!-- =================================================================== --> <property name="checkstyle.location" value="${lib-tools}/checkstyle-5.5-all.jar" /> - <property name="checkstyle.noframes.xslt" value="${basedir}/checkstyle-noframes.xsl" /> <property name="checkstyle.config" value="${basedir}/checkstyle-5.5.xml" /> <path id="checkstyle-classpath"> - <path refid="libs-build-classpath"/> <pathelement location="${checkstyle.location}"/> </path> <condition property="checkstyle.avail"> @@ -1053,20 +1056,18 @@ NOTE: <available classname="com.puppycrawl.tools.checkstyle.CheckStyleTask"> <classpath refid="checkstyle-classpath"/> </available> - <available file="${checkstyle.noframes.xslt}"/> <available file="${checkstyle.config}"/> </and> </condition> <target name="checkstyle-avail" unless="checkstyle.avail"> <echo message="Checkstyle support NOT present. Please download it from http://checkstyle.sf.net/ and"/> <echo message="... please provide ${checkstyle.location}"/> - <echo message="... please provide ${checkstyle.noframes.xslt}"/> <echo message="... please provide ${checkstyle.config}"/> </target> <target name="checkstyle" depends="package, checkstyle-avail" if="checkstyle.avail" description="Runs Checkstyle for a code quality report"> <taskdef name="checkstyle" classname="com.puppycrawl.tools.checkstyle.CheckStyleTask" classpathref="checkstyle-classpath"/> <mkdir dir="${build.dir}"/> - <checkstyle config="${checkstyle.config}" failonviolation="false"> + <checkstyle config="${checkstyle.config}" failonviolation="true" maxWarnings="0"> <classpath> <path refid="checkstyle-classpath"/> <pathelement location="${build.classes.dir}"/> @@ -1074,9 +1075,10 @@ NOTE: <pathelement location="${build.codegen-classes.dir}"/> </classpath> <fileset dir="${src.dir}" includes="**/*.java"/> + <fileset dir="${test.dir}" includes="**/*.java"/> <formatter type="xml" toFile="${build.dir}/report_checkstyle.xml"/> + <formatter type="plain"/> </checkstyle> - <xslt in="${build.dir}/report_checkstyle.xml" out="${build.dir}/report_checkstyle.html" style="${checkstyle.noframes.xslt}"/> </target> <!-- =================================================================== --> <!-- PMD --> @@ -1507,7 +1509,7 @@ NOTE: <!-- Special target for Gump --> <!-- =================================================================== --> <target name="gump" depends="package,transcoder-pkg"/> - <target name="gump-test" depends="junit-all"> + <target name="gump-test" depends="junit-all,checkstyle"> <fail> <condition> <or> diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml index 7dc583dbb..050f5dab4 100644 --- a/checkstyle-suppressions.xml +++ b/checkstyle-suppressions.xml @@ -6,4 +6,7 @@ <suppress files="org/apache/fop/complexscripts/bidi/GenerateBidiTestData.java" checks="SimplifyBooleanReturn"/> <suppress files="org/apache/fop/complexscripts/scripts/ArabicScriptProcessor.java" checks="SimplifyBooleanReturn"/> <suppress files="org/apache/fop/complexscripts/util/CharScript.java" checks="SimplifyBooleanReturn"/> + <suppress files="org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java" checks="AvoidNestedBlocks"/> + <suppress files="org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java" checks="AvoidNestedBlocks"/> + <suppress files="org/apache/fop/fo/flow/MarkersTestCase.java" checks="LocalVariableName"/> </suppressions> diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml index 46e6e1675..4dc4cb10b 100644 --- a/findbugs-exclude.xml +++ b/findbugs-exclude.xml @@ -1,6 +1,567 @@ <?xml version="1.0" encoding="utf-8"?> <FindBugsFilter> <Match> + <Bug pattern="BC_UNCONFIRMED_CAST_OF_RETURN_VALUE"/> + <Or> + <And> + <Class name="org.apache.fop.afp.AFPStreamer"/> + <Method name="close"/> + </And> + <And> + <Class name="org.apache.fop.area.Page"/> + <Method name="isEmpty"/> + </And> + <And> + <Class name="org.apache.fop.area.PageViewport"/> + <Method name="getBodyRegion"/> + </And> + <And> + <Class name="org.apache.fop.area.inline.InlineArea"/> + <Method name="notifyIPDVariation"/> + </And> + <And> + <Class name="org.apache.fop.area.inline.TextArea"/> + <Method name="getText"/> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.BlockStackingLayoutManager"/> + <Or> + <Method name="discardSpace"/> + <Method name="negotiateBPDAdjustment"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.FlowLayoutManager"/> + <Or> + <Method name="discardSpace"/> + <Method name="negotiateBPDAdjustment"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.PageBreakingAlgorithm"/> + <Or> + <Method name="createFootnotePages"/> + <Method name="finish"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.PageSequenceLayoutManager"/> + <Method name="activateLayout"/> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.inline.LineLayoutManager"/> + <Or> + <Method name="getChangedKnuthElements"/> + <Method name="negotiateBPDAdjustment"/> + <Method name="postProcessLineBreaks"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.inline.TextLayoutManager"/> + <Or> + <Method name="addALetterSpaceTo"/> + <Method name="addAreas"/> + <Method name="applyChanges"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.table.RowPainter"/> + <Method name="addAreasAndFlushRow"/> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.table.TableStepper"/> + <Method name="activateCells"/> + </And> + <And> + <Class name="org.apache.fop.render.AbstractRenderer"/> + <Method name="renderRegionViewport"/> + </And> + <And> + <Class name="org.apache.fop.render.afp.AFPImageHandler"/> + <Method name="generateDataObjectInfo"/> + </And> + <And> + <Class name="org.apache.fop.render.afp.AFPImageHandlerGraphics2D"/> + <Method name="handleImage"/> + </And> + <And> + <Class name="org.apache.fop.render.afp.AFPImageHandlerRawJPEG"/> + <Method name="handleImage"/> + </And> + <And> + <Class name="org.apache.fop.render.afp.AFPImageHandlerRenderedImage"/> + <Method name="handleImage"/> + </And> + <And> + <Class name="org.apache.fop.render.afp.AFPImageHandlerSVG"/> + <Method name="handleImage"/> + </And> + <And> + <Class name="org.apache.fop.render.intermediate.IFParser"/> + <Method name="parse"/> + </And> + <And> + <Class name="org.apache.fop.render.intermediate.IFParser$Handler"/> + <Method name="handleIFException"/> + </And> + <And> + <Class name="org.apache.fop.render.intermediate.IFRenderer"/> + <Or> + <Method name="handleIFExceptionWithIOException"/> + <Method name="renderSpace"/> + <Method name="renderWord"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.pdf.PDFRenderingUtil"/> + <Or> + <Method name="populateArray"/> + <Method name="populateDictionary"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.pdf.extensions.PDFArrayElement"/> + <Method name="getArrayExtension"/> + </And> + <And> + <Class name="org.apache.fop.render.pdf.extensions.PDFDictionaryElement"/> + <Method name="getDictionaryExtension"/> + </And> + <And> + <Class name="org.apache.fop.render.pdf.extensions.PDFReferenceElement"/> + <Method name="processNode"/> + </And> + <And> + <Class name="org.apache.fop.render.xml.XMLRenderer"/> + <Method name="renderRegionViewport"/> + </And> + <And> + <Class name="org.apache.fop.svg.PDFGraphics2D"/> + <Method name="applyUnknownPaint"/> + </And> + </Or> + </Match> + <Match> + <Bug pattern="DM_DEFAULT_ENCODING"/> + <Or> + <And> + <Class name="org.apache.fop.afp.fonts.CharacterSet"/> + <Or> + <Method name="getNameBytes"/> + <Method name="getBytes"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.afp.modca.AbstractNamedAFPObject"/> + <Or> + <Method name="getNameBytes"/> + <Method name="getBytes"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.afp.modca.triplets.AttributeValueTriplet"/> + <Or> + <Method name="writeToStream"/> + <Method name="getBytes"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.fonts.autodetect.WindowsFontDirFinder"/> + <Or> + <Method name="getWinDir"/> + <Method name="<init>"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.hyphenation.HyphenationTree"/> + <Or> + <Method name="main"/> + <Method name="<init>"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.pdf.PDFDocument"/> + <Or> + <Method name="encode"/> + <Method name="getBytes"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.afp.AFPPainter$AFPBorderPainterAdapter"/> + <Or> + <Method name="hash"/> + <Method name="getBytes"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.rtf.RTFHandler"/> + <Or> + <Method name="startDocument"/> + <Method name="<init>"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFile"/> + <Or> + <Method name="main"/> + <Method name="<init>"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.tools.anttasks.FileCompare"/> + <Or> + <Method name="execute"/> + <Method name="<init>"/> + </Or> + </And> + </Or> + </Match> + <Match> + <Bug pattern="FE_FLOATING_POINT_EQUALITY"/> + <Or> + <And> + <Class name="org.apache.fop.afp.modca.GraphicsObject"/> + <Method name="setLineWidth"/> + </And> + <And> + <Class name="org.apache.fop.fonts.type1.AFMFile"/> + <Method name="overridePrimaryEncoding"/> + </And> + </Or> + </Match> + <Match> + <Bug pattern="BC_BAD_CAST_TO_CONCRETE_COLLECTION"/> + <Or> + <And> + <Class name="org.apache.fop.area.AreaTreeObject"/> + <Or> + <Field name="extensionAttachments"/> + <Field name="foreignAttributes"/> + <Method name="clone"/> + </Or> + </And> + </Or> + </Match> + <Match> + <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE"/> + <Or> + <And> + <Class name="org.apache.fop.complexscripts.fonts.GlyphPositioningTable"/> + <Or> + <Method name="position"/> + <Method name="matchLookups"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable"/> + <Or> + <Method name="substitute"/> + <Method name="matchLookups"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader"/> + <Or> + <Method name="constructGDEF"/> + <Method name="constructGDEFSubtables"/> + <Method name="constructGPOS"/> + <Method name="constructLookups"/> + <Method name="constructGPOSSubtables"/> + <Method name="constructGSUB"/> + <Method name="constructGSUBSubtables"/> + <Method name="readChainedContextualPosTableFormat3"/> + <Method name="readChainedContextualSubTableFormat3"/> + <Method name="readContextualPosTableFormat3"/> + <Method name="readContextualSubTableFormat3"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.complexscripts.util.GlyphSequence$CharAssociation"/> + <Or> + <Field name="predications"/> + <Method name="join"/> + <Method name="extractIntervals"/> + <Method name="mergePredication"/> + <Method name="setPredication"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.fonts.apps.PFMReader"/> + <Or> + <Method name="main"/> + <Method name="loadPFM"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.fonts.substitute.FontQualifier"/> + <Or> + <Method name="setFontStyle"/> + <Method name="valueOf"/> + <Method name="setFontWeight"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.hyphenation.Hyphenator"/> + <Or> + <Method name="getResourceStream"/> + <Method name="getMethod"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.hyphenation.PatternParser"/> + <Or> + <Method name="main"/> + <Method name="<init>"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.pdf.PDFMetadata"/> + <Or> + <Method name="populateStreamDict"/> + <Method name="buildFilterDictEntries"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.AbstractRenderer"/> + <Or> + <Method name="renderBodyRegion"/> + <Method name="getBeforeFloat"/> + <Method name="getFootnote"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.afp.extensions.AFPExtensionHandler"/> + <Or> + <Method name="endElement"/> + <Method name="<init>"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.pdf.extensions.PDFEmbeddedFileElement"/> + <Or> + <Method name="processNode"/> + <Method name="getURL"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.util.ColorUtil"/> + <Or> + <Method name="parseAsFopRgbIcc"/> + <Method name="trim"/> + <Method name="parseAsFopRgbNamedColor"/> + <Method name="unescapeString"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.util.XMLUtil"/> + <Or> + <Method name="decodePositionAdjustments"/> + <Method name="split"/> + </Or> + </And> + </Or> + </Match> + <Match> + <Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"/> + <Or> + <And> + <Class name="org.apache.fop.complexscripts.fonts.GlyphProcessingState"/> + <Field name="classMatchSet"/> + </And> + <And> + <Class name="org.apache.fop.fo.XMLWhiteSpaceHandler$PendingInline"/> + <Field name="fo"/> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.inline.InlineStackingLayoutManager"/> + <Field name="extraBPD"/> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.table.TableRowIterator"/> + <Field name="table"/> + </And> + <And> + <Class name="org.apache.fop.pdf.PDFCMap"/> + <Or> + <Field name="base"/> + <Field name="sysInfo"/> + <Field name="wMode"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic"/> + <Or> + <Field name="heightPercent"/> + <Field name="widthPercent"/> + </Or> + </And> + </Or> + </Match> + <Match> + <Bug pattern="UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR"/> + <Or> + <And> + <Class name="org.apache.fop.fo.XMLObj"/> + <Or> + <Field name="doc"/> + <Field name="element"/> + <Method name="characters"/> + <Method name="getDimension"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.fo.flow.table.TableCellContainer"/> + <Or> + <Field name="pendingSpans"/> + <Method name="addTableCellChild"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.fo.pagination.AbstractPageSequence"/> + <Or> + <Field name="initialPageNumber"/> + <Method name="initPageNumber"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.afp.extensions.AbstractAFPExtensionObject"/> + <Or> + <Field name="extensionAttachment"/> + <Method name="processNode"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler"/> + <Or> + <Field name="outputStream"/> + <Method name="rewritePostScriptFile"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.java2d.Java2DSVGHandler$Java2DInfo"/> + <Or> + <Field name="state"/> + <Method name="renderSVGDocument"/> + </Or> + </And> + </Or> + </Match> + <Match> + <Bug pattern="SBSC_USE_STRINGBUFFER_CONCATENATION"/> + <And> + <Class name="org.apache.fop.fo.properties.GenericShorthandParser"/> + <Method name="convertValueForProperty"/> + </And> + </Match> + <Match> + <Bug pattern="EI_EXPOSE_REP2"/> + <Or> + <And> + <Class name="org.apache.fop.fonts.GlyphMapping"/> + <Or> + <Field name="gposAdjustments"/> + <Method name="<init>"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.fonts.MultiByteFont"/> + <Or> + <Field name="boundingBoxes"/> + <Method name="setBBoxArray"/> + </Or> + </And> + </Or> + </Match> + <Match> + <Bug pattern="OS_OPEN_STREAM_EXCEPTION_PATH"/> + <And> + <Class name="org.apache.fop.hyphenation.SerializeHyphPattern"/> + <Method name="serializeFile"/> + </And> + </Match> + <Match> + <Bug pattern="BC_UNCONFIRMED_CAST"/> + <Or> + <And> + <Class name="org.apache.fop.layoutmgr.PageBreakingAlgorithm"/> + <Or> + <Field name="best"/> + <Field name="next"/> + <Method name="createNode"/> + <Method name="finish"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.inline.ContentLayoutManager"/> + <Or> + <Field name="holder"/> + <Method name="addAreas"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.layoutmgr.inline.PageNumberLayoutManager"/> + <Or> + <Field name="curArea"/> + <Method name="getEffectiveArea"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFontTable"/> + <Or> + <Field name="parent"/> + <Method name="writeRtfContent"/> + </Or> + </And> + <And> + <Class name="org.apache.fop.svg.PDFGraphics2D"/> + <Method name="registerFunction"/> + </And> + </Or> + </Match> + <Match> + <Bug pattern="PZLA_PREFER_ZERO_LENGTH_ARRAYS"/> + <And> + <Class name="org.apache.fop.layoutmgr.inline.TextLayoutManager$TextAreaBuilder"/> + <Method name="getMappingBidiLevels"/> + </And> + </Match> + <Match> + <Bug pattern="NP_LOAD_OF_KNOWN_NULL_VALUE"/> + <And> + <Class name="org.apache.fop.pdf.PDFFactory"/> + <Method name="makeFontFile"/> + </And> + </Match> + <Match> + <Bug pattern="SE_BAD_FIELD"/> + <And> + <Class name="org.apache.fop.render.awt.viewer.ImageProxyPanel"/> + <Field name="imageRef"/> + </And> + </Match> + <Match> + <Bug pattern="SE_BAD_FIELD_STORE"/> + <And> + <Class name="org.apache.fop.render.awt.viewer.ImageProxyPanel"/> + <Field name="imageRef"/> + </And> + </Match> + <Match> + <Bug pattern="RC_REF_COMPARISON_BAD_PRACTICE"/> + <Or> + <And> + <Class name="org.apache.fop.render.xml.XMLRenderer"/> + <Or> + <Field name="END_INDENT"/> + <Field name="FONT"/> + <Field name="START_INDENT"/> + <Method name="addTraitAttributes"/> + </Or> + </And> + </Or> + </Match> + + <Match> <Class name="org.apache.fop.fonts.truetype.OpenFont$1"/> <Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON"/> </Match> diff --git a/lib/batik-all-1.7.jar b/lib/batik-all-1.7.jar Binary files differdeleted file mode 100644 index 589328581..000000000 --- a/lib/batik-all-1.7.jar +++ /dev/null diff --git a/lib/batik-all-trunk.jar b/lib/batik-all-trunk.jar Binary files differnew file mode 100644 index 000000000..08c1a383a --- /dev/null +++ b/lib/batik-all-trunk.jar diff --git a/lib/fontbox-1.8.3-patched.jar b/lib/fontbox-1.8.4-patched.jar Binary files differindex 57460be06..f608b4409 100644 --- a/lib/fontbox-1.8.3-patched.jar +++ b/lib/fontbox-1.8.4-patched.jar diff --git a/lib/xmlgraphics-commons-svn-trunk.jar b/lib/xmlgraphics-commons-svn-trunk.jar Binary files differindex b85214c10..64768ff23 100644 --- a/lib/xmlgraphics-commons-svn-trunk.jar +++ b/lib/xmlgraphics-commons-svn-trunk.jar diff --git a/src/codegen/fonts/Courier.xml b/src/codegen/fonts/Courier.xml index be977e22e..075699427 100644 --- a/src/codegen/fonts/Courier.xml +++ b/src/codegen/fonts/Courier.xml @@ -22,275 +22,246 @@ <family-name>Courier</family-name> <class-name>Courier</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>562</cap-height> <x-height>426</x-height> <ascender>629</ascender> <descender>-157</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="600"/> - <char name="AE" width="600"/> - <char name="Aacute" width="600"/> - <char name="Acircumflex" width="600"/> - <char name="Adieresis" width="600"/> - <char name="Agrave" width="600"/> - <char name="Aring" width="600"/> - <char name="Atilde" width="600"/> - <char name="B" width="600"/> - <char name="C" width="600"/> - <char name="Ccedilla" width="600"/> - <char name="D" width="600"/> - <char name="E" width="600"/> - <char name="Eacute" width="600"/> - <char name="Ecircumflex" width="600"/> - <char name="Edieresis" width="600"/> - <char name="Egrave" width="600"/> - <char name="Eth" width="600"/> - <char name="Euro" width="600"/> - <char name="F" width="600"/> - <char name="G" width="600"/> - <char name="Gcaron" width="600"/> - <char name="H" width="600"/> - <char name="I" width="600"/> - <char name="IJ" width="600"/> - <char name="Iacute" width="600"/> - <char name="Icircumflex" width="600"/> - <char name="Idieresis" width="600"/> - <char name="Idot" width="600"/> - <char name="Igrave" width="600"/> - <char name="J" width="600"/> - <char name="K" width="600"/> - <char name="L" width="600"/> - <char name="LL" width="600"/> - <char name="Lslash" width="600"/> - <char name="M" width="600"/> - <char name="N" width="600"/> - <char name="Ntilde" width="600"/> - <char name="O" width="600"/> - <char name="OE" width="600"/> - <char name="Oacute" width="600"/> - <char name="Ocircumflex" width="600"/> - <char name="Odieresis" width="600"/> - <char name="Ograve" width="600"/> - <char name="Oslash" width="600"/> - <char name="Otilde" width="600"/> - <char name="P" width="600"/> - <char name="Q" width="600"/> - <char name="R" width="600"/> - <char name="S" width="600"/> - <char name="Scaron" width="600"/> - <char name="Scedilla" width="600"/> - <char name="T" width="600"/> - <char name="Thorn" width="600"/> - <char name="U" width="600"/> - <char name="Uacute" width="600"/> - <char name="Ucircumflex" width="600"/> - <char name="Udieresis" width="600"/> - <char name="Ugrave" width="600"/> - <char name="V" width="600"/> - <char name="W" width="600"/> - <char name="X" width="600"/> - <char name="Y" width="600"/> - <char name="Yacute" width="600"/> - <char name="Ydieresis" width="600"/> - <char name="Z" width="600"/> - <char name="Zcaron" width="600"/> - <char name="a" width="600"/> - <char name="aacute" width="600"/> - <char name="acircumflex" width="600"/> - <char name="acute" width="600"/> - <char name="adieresis" width="600"/> - <char name="ae" width="600"/> - <char name="agrave" width="600"/> - <char name="ampersand" width="600"/> - <char name="aring" width="600"/> - <char name="arrowboth" width="600"/> - <char name="arrowdown" width="600"/> - <char name="arrowleft" width="600"/> - <char name="arrowright" width="600"/> - <char name="arrowup" width="600"/> - <char name="asciicircum" width="600"/> - <char name="asciitilde" width="600"/> - <char name="asterisk" width="600"/> - <char name="at" width="600"/> - <char name="atilde" width="600"/> - <char name="b" width="600"/> - <char name="backslash" width="600"/> - <char name="bar" width="600"/> - <char name="braceleft" width="600"/> - <char name="braceright" width="600"/> - <char name="bracketleft" width="600"/> - <char name="bracketright" width="600"/> - <char name="breve" width="600"/> - <char name="brokenbar" width="600"/> - <char name="bullet" width="600"/> - <char name="c" width="600"/> - <char name="caron" width="600"/> - <char name="ccedilla" width="600"/> - <char name="cedilla" width="600"/> - <char name="cent" width="600"/> - <char name="center" width="600"/> - <char name="circumflex" width="600"/> - <char name="colon" width="600"/> - <char name="comma" width="600"/> - <char name="copyright" width="600"/> - <char name="currency" width="600"/> - <char name="d" width="600"/> - <char name="dagger" width="600"/> - <char name="daggerdbl" width="600"/> - <char name="dectab" width="600"/> - <char name="degree" width="600"/> - <char name="dieresis" width="600"/> - <char name="divide" width="600"/> - <char name="dollar" width="600"/> - <char name="dotaccent" width="600"/> - <char name="dotlessi" width="600"/> - <char name="down" width="600"/> - <char name="e" width="600"/> - <char name="eacute" width="600"/> - <char name="ecircumflex" width="600"/> - <char name="edieresis" width="600"/> - <char name="egrave" width="600"/> - <char name="eight" width="600"/> - <char name="ellipsis" width="600"/> - <char name="emdash" width="600"/> - <char name="endash" width="600"/> - <char name="equal" width="600"/> - <char name="eth" width="600"/> - <char name="exclam" width="600"/> - <char name="exclamdown" width="600"/> - <char name="f" width="600"/> - <char name="fi" width="600"/> - <char name="five" width="600"/> - <char name="fl" width="600"/> - <char name="florin" width="600"/> - <char name="format" width="600"/> - <char name="four" width="600"/> - <char name="fraction" width="600"/> - <char name="g" width="600"/> - <char name="gcaron" width="600"/> - <char name="germandbls" width="600"/> - <char name="grave" width="600"/> - <char name="graybox" width="600"/> - <char name="greater" width="600"/> - <char name="guillemotleft" width="600"/> - <char name="guillemotright" width="600"/> - <char name="guilsinglleft" width="600"/> - <char name="guilsinglright" width="600"/> - <char name="h" width="600"/> - <char name="hungarumlaut" width="600"/> - <char name="hyphen" width="600"/> - <char name="i" width="600"/> - <char name="iacute" width="600"/> - <char name="icircumflex" width="600"/> - <char name="idieresis" width="600"/> - <char name="igrave" width="600"/> - <char name="ij" width="600"/> - <char name="indent" width="600"/> - <char name="j" width="600"/> - <char name="k" width="600"/> - <char name="l" width="600"/> - <char name="largebullet" width="600"/> - <char name="left" width="600"/> - <char name="less" width="600"/> - <char name="lira" width="600"/> - <char name="ll" width="600"/> - <char name="logicalnot" width="600"/> - <char name="lslash" width="600"/> - <char name="m" width="600"/> - <char name="macron" width="600"/> - <char name="merge" width="600"/> - <char name="minus" width="600"/> - <char name="mu" width="600"/> - <char name="multiply" width="600"/> - <char name="n" width="600"/> - <char name="nine" width="600"/> - <char name="notegraphic" width="600"/> - <char name="ntilde" width="600"/> - <char name="numbersign" width="600"/> - <char name="o" width="600"/> - <char name="oacute" width="600"/> - <char name="ocircumflex" width="600"/> - <char name="odieresis" width="600"/> - <char name="oe" width="600"/> - <char name="ogonek" width="600"/> - <char name="ograve" width="600"/> - <char name="one" width="600"/> - <char name="onehalf" width="600"/> - <char name="onequarter" width="600"/> - <char name="onesuperior" width="600"/> - <char name="ordfeminine" width="600"/> - <char name="ordmasculine" width="600"/> - <char name="oslash" width="600"/> - <char name="otilde" width="600"/> - <char name="overscore" width="600"/> - <char name="p" width="600"/> - <char name="paragraph" width="600"/> - <char name="parenleft" width="600"/> - <char name="parenright" width="600"/> - <char name="percent" width="600"/> - <char name="period" width="600"/> - <char name="periodcentered" width="600"/> - <char name="perthousand" width="600"/> - <char name="plus" width="600"/> - <char name="plusminus" width="600"/> - <char name="prescription" width="600"/> - <char name="q" width="600"/> - <char name="question" width="600"/> - <char name="questiondown" width="600"/> - <char name="quotedbl" width="600"/> - <char name="quotedblbase" width="600"/> - <char name="quotedblleft" width="600"/> - <char name="quotedblright" width="600"/> - <char name="quoteleft" width="600"/> - <char name="quoteright" width="600"/> - <char name="quotesinglbase" width="600"/> - <char name="quotesingle" width="600"/> - <char name="r" width="600"/> - <char name="registered" width="600"/> - <char name="return" width="600"/> - <char name="ring" width="600"/> - <char name="s" width="600"/> - <char name="scaron" width="600"/> - <char name="scedilla" width="600"/> - <char name="section" width="600"/> - <char name="semicolon" width="600"/> - <char name="seven" width="600"/> - <char name="six" width="600"/> - <char name="slash" width="600"/> - <char name="space" width="600"/> + <char-metrics> + <char name="A" width="600" llx="3" lly="0" urx="597" ury="562"/> + <char name="AE" width="600" llx="3" lly="0" urx="550" ury="562"/> + <char name="Aacute" width="600" llx="3" lly="0" urx="597" ury="805"/> + <char name="Acircumflex" width="600" llx="3" lly="0" urx="597" ury="787"/> + <char name="Adieresis" width="600" llx="3" lly="0" urx="597" ury="753"/> + <char name="Agrave" width="600" llx="3" lly="0" urx="597" ury="805"/> + <char name="Aring" width="600" llx="3" lly="0" urx="597" ury="750"/> + <char name="Atilde" width="600" llx="3" lly="0" urx="597" ury="729"/> + <char name="B" width="600" llx="43" lly="0" urx="559" ury="562"/> + <char name="C" width="600" llx="41" lly="-18" urx="540" ury="580"/> + <char name="Ccedilla" width="600" llx="41" lly="-151" urx="540" ury="580"/> + <char name="D" width="600" llx="43" lly="0" urx="574" ury="562"/> + <char name="E" width="600" llx="53" lly="0" urx="550" ury="562"/> + <char name="Eacute" width="600" llx="53" lly="0" urx="550" ury="805"/> + <char name="Ecircumflex" width="600" llx="53" lly="0" urx="550" ury="787"/> + <char name="Edieresis" width="600" llx="53" lly="0" urx="550" ury="753"/> + <char name="Egrave" width="600" llx="53" lly="0" urx="550" ury="805"/> + <char name="Eth" width="600" llx="30" lly="0" urx="574" ury="562"/> + <char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="600" llx="53" lly="0" urx="545" ury="562"/> + <char name="G" width="600" llx="31" lly="-18" urx="575" ury="580"/> + <char name="H" width="600" llx="32" lly="0" urx="568" ury="562"/> + <char name="I" width="600" llx="96" lly="0" urx="504" ury="562"/> + <char name="Iacute" width="600" llx="96" lly="0" urx="504" ury="805"/> + <char name="Icircumflex" width="600" llx="96" lly="0" urx="504" ury="787"/> + <char name="Idieresis" width="600" llx="96" lly="0" urx="504" ury="753"/> + <char name="Igrave" width="600" llx="96" lly="0" urx="504" ury="805"/> + <char name="J" width="600" llx="34" lly="-18" urx="566" ury="562"/> + <char name="K" width="600" llx="38" lly="0" urx="582" ury="562"/> + <char name="L" width="600" llx="47" lly="0" urx="554" ury="562"/> + <char name="Lslash" width="600" llx="47" lly="0" urx="554" ury="562"/> + <char name="M" width="600" llx="4" lly="0" urx="596" ury="562"/> + <char name="N" width="600" llx="7" lly="-13" urx="593" ury="562"/> + <char name="Ntilde" width="600" llx="7" lly="-13" urx="593" ury="729"/> + <char name="O" width="600" llx="43" lly="-18" urx="557" ury="580"/> + <char name="OE" width="600" llx="7" lly="0" urx="567" ury="562"/> + <char name="Oacute" width="600" llx="43" lly="-18" urx="557" ury="805"/> + <char name="Ocircumflex" width="600" llx="43" lly="-18" urx="557" ury="787"/> + <char name="Odieresis" width="600" llx="43" lly="-18" urx="557" ury="753"/> + <char name="Ograve" width="600" llx="43" lly="-18" urx="557" ury="805"/> + <char name="Oslash" width="600" llx="43" lly="-80" urx="557" ury="629"/> + <char name="Otilde" width="600" llx="43" lly="-18" urx="557" ury="729"/> + <char name="P" width="600" llx="79" lly="0" urx="558" ury="562"/> + <char name="Q" width="600" llx="43" lly="-138" urx="557" ury="580"/> + <char name="R" width="600" llx="38" lly="0" urx="588" ury="562"/> + <char name="S" width="600" llx="72" lly="-20" urx="529" ury="580"/> + <char name="Scaron" width="600" llx="72" lly="-20" urx="529" ury="802"/> + <char name="Scedilla" width="600" llx="72" lly="-151" urx="529" ury="580"/> + <char name="T" width="600" llx="38" lly="0" urx="563" ury="562"/> + <char name="Thorn" width="600" llx="79" lly="0" urx="538" ury="562"/> + <char name="U" width="600" llx="17" lly="-18" urx="583" ury="562"/> + <char name="Uacute" width="600" llx="17" lly="-18" urx="583" ury="805"/> + <char name="Ucircumflex" width="600" llx="17" lly="-18" urx="583" ury="787"/> + <char name="Udieresis" width="600" llx="17" lly="-18" urx="583" ury="753"/> + <char name="Ugrave" width="600" llx="17" lly="-18" urx="583" ury="805"/> + <char name="V" width="600" llx="-4" lly="-13" urx="604" ury="562"/> + <char name="W" width="600" llx="-3" lly="-13" urx="603" ury="562"/> + <char name="X" width="600" llx="23" lly="0" urx="577" ury="562"/> + <char name="Y" width="600" llx="24" lly="0" urx="576" ury="562"/> + <char name="Yacute" width="600" llx="24" lly="0" urx="576" ury="805"/> + <char name="Ydieresis" width="600" llx="24" lly="0" urx="576" ury="753"/> + <char name="Z" width="600" llx="86" lly="0" urx="514" ury="562"/> + <char name="Zcaron" width="600" llx="86" lly="0" urx="514" ury="802"/> + <char name="a" width="600" llx="53" lly="-15" urx="559" ury="441"/> + <char name="aacute" width="600" llx="53" lly="-15" urx="559" ury="672"/> + <char name="acircumflex" width="600" llx="53" lly="-15" urx="559" ury="654"/> + <char name="acute" width="600" llx="242" lly="497" urx="469" ury="672"/> + <char name="adieresis" width="600" llx="53" lly="-15" urx="559" ury="620"/> + <char name="ae" width="600" llx="19" lly="-15" urx="570" ury="441"/> + <char name="agrave" width="600" llx="53" lly="-15" urx="559" ury="672"/> + <char name="ampersand" width="600" llx="63" lly="-15" urx="538" ury="543"/> + <char name="aring" width="600" llx="53" lly="-15" urx="559" ury="627"/> + <char name="asciicircum" width="600" llx="94" lly="354" urx="506" ury="622"/> + <char name="asciitilde" width="600" llx="63" lly="197" urx="540" ury="320"/> + <char name="asterisk" width="600" llx="116" lly="257" urx="484" ury="607"/> + <char name="at" width="600" llx="77" lly="-15" urx="533" ury="622"/> + <char name="atilde" width="600" llx="53" lly="-15" urx="559" ury="606"/> + <char name="b" width="600" llx="14" lly="-15" urx="575" ury="629"/> + <char name="backslash" width="600" llx="118" lly="-80" urx="482" ury="629"/> + <char name="bar" width="600" llx="275" lly="-250" urx="326" ury="750"/> + <char name="braceleft" width="600" llx="182" lly="-108" urx="437" ury="622"/> + <char name="braceright" width="600" llx="163" lly="-108" urx="418" ury="622"/> + <char name="bracketleft" width="600" llx="269" lly="-108" urx="442" ury="622"/> + <char name="bracketright" width="600" llx="158" lly="-108" urx="331" ury="622"/> + <char name="breve" width="600" llx="153" lly="501" urx="447" ury="609"/> + <char name="brokenbar" width="600" llx="275" lly="-175" urx="326" ury="675"/> + <char name="bullet" width="600" llx="172" lly="130" urx="428" ury="383"/> + <char name="c" width="600" llx="66" lly="-15" urx="529" ury="441"/> + <char name="caron" width="600" llx="124" lly="492" urx="476" ury="669"/> + <char name="ccedilla" width="600" llx="66" lly="-151" urx="529" ury="441"/> + <char name="cedilla" width="600" llx="224" lly="-151" urx="362" ury="10"/> + <char name="cent" width="600" llx="96" lly="-49" urx="500" ury="614"/> + <char name="circumflex" width="600" llx="124" lly="477" urx="476" ury="654"/> + <char name="colon" width="600" llx="229" lly="-15" urx="371" ury="385"/> + <char name="comma" width="600" llx="181" lly="-112" urx="344" ury="122"/> + <char name="copyright" width="600" llx="0" lly="-18" urx="600" ury="580"/> + <char name="currency" width="600" llx="73" lly="58" urx="527" ury="506"/> + <char name="d" width="600" llx="45" lly="-15" urx="591" ury="629"/> + <char name="dagger" width="600" llx="141" lly="-78" urx="459" ury="580"/> + <char name="daggerdbl" width="600" llx="141" lly="-78" urx="459" ury="580"/> + <char name="degree" width="600" llx="123" lly="269" urx="477" ury="622"/> + <char name="dieresis" width="600" llx="148" lly="537" urx="453" ury="640"/> + <char name="divide" width="600" llx="87" lly="48" urx="513" ury="467"/> + <char name="dollar" width="600" llx="105" lly="-126" urx="496" ury="662"/> + <char name="dotaccent" width="600" llx="249" lly="537" urx="352" ury="640"/> + <char name="dotlessi" width="600" llx="95" lly="0" urx="505" ury="426"/> + <char name="e" width="600" llx="66" lly="-15" urx="548" ury="441"/> + <char name="eacute" width="600" llx="66" lly="-15" urx="548" ury="672"/> + <char name="ecircumflex" width="600" llx="66" lly="-15" urx="548" ury="654"/> + <char name="edieresis" width="600" llx="66" lly="-15" urx="548" ury="620"/> + <char name="egrave" width="600" llx="66" lly="-15" urx="548" ury="672"/> + <char name="eight" width="600" llx="102" lly="-15" urx="498" ury="622"/> + <char name="ellipsis" width="600" llx="37" lly="-15" urx="563" ury="111"/> + <char name="emdash" width="600" llx="0" lly="231" urx="600" ury="285"/> + <char name="endash" width="600" llx="75" lly="231" urx="525" ury="285"/> + <char name="equal" width="600" llx="80" lly="138" urx="520" ury="376"/> + <char name="eth" width="600" llx="62" lly="-15" urx="538" ury="629"/> + <char name="exclam" width="600" llx="236" lly="-15" urx="364" ury="572"/> + <char name="exclamdown" width="600" llx="236" lly="-157" urx="364" ury="430"/> + <char name="f" width="600" llx="114" lly="0" urx="531" ury="629"/> + <char name="fi" width="600" llx="3" lly="0" urx="597" ury="629"/> + <char name="five" width="600" llx="92" lly="-15" urx="497" ury="607"/> + <char name="fl" width="600" llx="3" lly="0" urx="597" ury="629"/> + <char name="florin" width="600" llx="4" lly="-143" urx="539" ury="622"/> + <char name="four" width="600" llx="78" lly="0" urx="500" ury="622"/> + <char name="fraction" width="600" llx="92" lly="-57" urx="509" ury="665"/> + <char name="g" width="600" llx="45" lly="-157" urx="566" ury="441"/> + <char name="germandbls" width="600" llx="48" lly="-15" urx="588" ury="629"/> + <char name="grave" width="600" llx="151" lly="497" urx="378" ury="672"/> + <char name="greater" width="600" llx="66" lly="42" urx="544" ury="472"/> + <char name="guillemotleft" width="600" llx="37" lly="70" urx="563" ury="446"/> + <char name="guillemotright" width="600" llx="37" lly="70" urx="563" ury="446"/> + <char name="guilsinglleft" width="600" llx="149" lly="70" urx="451" ury="446"/> + <char name="guilsinglright" width="600" llx="149" lly="70" urx="451" ury="446"/> + <char name="h" width="600" llx="18" lly="0" urx="582" ury="629"/> + <char name="hungarumlaut" width="600" llx="133" lly="497" urx="540" ury="672"/> + <char name="hyphen" width="600" llx="103" lly="231" urx="497" ury="285"/> + <char name="i" width="600" llx="95" lly="0" urx="505" ury="657"/> + <char name="iacute" width="600" llx="95" lly="0" urx="505" ury="672"/> + <char name="icircumflex" width="600" llx="94" lly="0" urx="505" ury="654"/> + <char name="idieresis" width="600" llx="95" lly="0" urx="505" ury="620"/> + <char name="igrave" width="600" llx="95" lly="0" urx="505" ury="672"/> + <char name="j" width="600" llx="82" lly="-157" urx="410" ury="657"/> + <char name="k" width="600" llx="43" lly="0" urx="580" ury="629"/> + <char name="l" width="600" llx="95" lly="0" urx="505" ury="629"/> + <char name="less" width="600" llx="41" lly="42" urx="519" ury="472"/> + <char name="logicalnot" width="600" llx="87" lly="108" urx="513" ury="369"/> + <char name="lslash" width="600" llx="95" lly="0" urx="505" ury="629"/> + <char name="m" width="600" llx="-5" lly="0" urx="605" ury="441"/> + <char name="macron" width="600" llx="120" lly="525" urx="480" ury="565"/> + <char name="minus" width="600" llx="80" lly="232" urx="520" ury="283"/> + <char name="mu" width="600" llx="21" lly="-157" urx="562" ury="426"/> + <char name="multiply" width="600" llx="87" lly="43" urx="515" ury="470"/> + <char name="n" width="600" llx="26" lly="0" urx="575" ury="441"/> + <char name="nine" width="600" llx="96" lly="-15" urx="489" ury="622"/> + <char name="ntilde" width="600" llx="26" lly="0" urx="575" ury="606"/> + <char name="numbersign" width="600" llx="93" lly="-32" urx="507" ury="639"/> + <char name="o" width="600" llx="62" lly="-15" urx="538" ury="441"/> + <char name="oacute" width="600" llx="62" lly="-15" urx="538" ury="672"/> + <char name="ocircumflex" width="600" llx="62" lly="-15" urx="538" ury="654"/> + <char name="odieresis" width="600" llx="62" lly="-15" urx="538" ury="620"/> + <char name="oe" width="600" llx="19" lly="-15" urx="559" ury="441"/> + <char name="ogonek" width="600" llx="211" lly="-172" urx="407" ury="4"/> + <char name="ograve" width="600" llx="62" lly="-15" urx="538" ury="672"/> + <char name="one" width="600" llx="96" lly="0" urx="505" ury="622"/> + <char name="onehalf" width="600" llx="0" lly="-57" urx="611" ury="665"/> + <char name="onequarter" width="600" llx="0" lly="-57" urx="600" ury="665"/> + <char name="onesuperior" width="600" llx="172" lly="249" urx="428" ury="622"/> + <char name="ordfeminine" width="600" llx="156" lly="249" urx="442" ury="580"/> + <char name="ordmasculine" width="600" llx="157" lly="249" urx="443" ury="580"/> + <char name="oslash" width="600" llx="62" lly="-80" urx="538" ury="506"/> + <char name="otilde" width="600" llx="62" lly="-15" urx="538" ury="606"/> + <char name="p" width="600" llx="9" lly="-157" urx="555" ury="441"/> + <char name="paragraph" width="600" llx="50" lly="-78" urx="511" ury="562"/> + <char name="parenleft" width="600" llx="269" lly="-108" urx="440" ury="622"/> + <char name="parenright" width="600" llx="160" lly="-108" urx="331" ury="622"/> + <char name="percent" width="600" llx="81" lly="-15" urx="518" ury="622"/> + <char name="period" width="600" llx="229" lly="-15" urx="371" ury="109"/> + <char name="periodcentered" width="600" llx="222" lly="189" urx="378" ury="327"/> + <char name="perthousand" width="600" llx="3" lly="-15" urx="600" ury="622"/> + <char name="plus" width="600" llx="80" lly="44" urx="520" ury="470"/> + <char name="plusminus" width="600" llx="87" lly="44" urx="513" ury="558"/> + <char name="q" width="600" llx="45" lly="-157" urx="591" ury="441"/> + <char name="question" width="600" llx="129" lly="-15" urx="492" ury="572"/> + <char name="questiondown" width="600" llx="108" lly="-157" urx="471" ury="430"/> + <char name="quotedbl" width="600" llx="187" lly="328" urx="413" ury="562"/> + <char name="quotedblbase" width="600" llx="143" lly="-134" urx="457" ury="100"/> + <char name="quotedblleft" width="600" llx="143" lly="328" urx="471" ury="562"/> + <char name="quotedblright" width="600" llx="143" lly="328" urx="457" ury="562"/> + <char name="quoteleft" width="600" llx="224" lly="328" urx="387" ury="562"/> + <char name="quoteright" width="600" llx="213" lly="328" urx="376" ury="562"/> + <char name="quotesinglbase" width="600" llx="213" lly="-134" urx="376" ury="100"/> + <char name="quotesingle" width="600" llx="259" lly="328" urx="341" ury="562"/> + <char name="r" width="600" llx="60" lly="0" urx="559" ury="441"/> + <char name="registered" width="600" llx="0" lly="-18" urx="600" ury="580"/> + <char name="ring" width="600" llx="218" lly="463" urx="382" ury="627"/> + <char name="s" width="600" llx="80" lly="-15" urx="513" ury="441"/> + <char name="scaron" width="600" llx="80" lly="-15" urx="513" ury="669"/> + <char name="scedilla" width="600" llx="80" lly="-151" urx="513" ury="441"/> + <char name="section" width="600" llx="113" lly="-78" urx="488" ury="580"/> + <char name="semicolon" width="600" llx="181" lly="-112" urx="371" ury="385"/> + <char name="seven" width="600" llx="82" lly="0" urx="483" ury="607"/> + <char name="six" width="600" llx="111" lly="-15" urx="497" ury="622"/> + <char name="slash" width="600" llx="125" lly="-80" urx="475" ury="629"/> + <char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="600"/> - <char name="square" width="600"/> - <char name="sterling" width="600"/> - <char name="stop" width="600"/> - <char name="t" width="600"/> - <char name="tab" width="600"/> - <char name="thorn" width="600"/> - <char name="three" width="600"/> - <char name="threequarters" width="600"/> - <char name="threesuperior" width="600"/> - <char name="tilde" width="600"/> - <char name="trademark" width="600"/> - <char name="two" width="600"/> - <char name="twosuperior" width="600"/> - <char name="u" width="600"/> - <char name="uacute" width="600"/> - <char name="ucircumflex" width="600"/> - <char name="udieresis" width="600"/> - <char name="ugrave" width="600"/> - <char name="underscore" width="600"/> - <char name="up" width="600"/> - <char name="v" width="600"/> - <char name="w" width="600"/> - <char name="x" width="600"/> - <char name="y" width="600"/> - <char name="yacute" width="600"/> - <char name="ydieresis" width="600"/> - <char name="yen" width="600"/> - <char name="z" width="600"/> - <char name="zcaron" width="600"/> - <char name="zero" width="600"/> - </widths> -</font-metrics>
\ No newline at end of file + <char name="sterling" width="600" llx="84" lly="-21" urx="521" ury="611"/> + <char name="t" width="600" llx="87" lly="-15" urx="530" ury="561"/> + <char name="thorn" width="600" llx="-6" lly="-157" urx="555" ury="629"/> + <char name="three" width="600" llx="75" lly="-15" urx="466" ury="622"/> + <char name="threequarters" width="600" llx="8" lly="-56" urx="593" ury="666"/> + <char name="threesuperior" width="600" llx="155" lly="240" urx="406" ury="622"/> + <char name="tilde" width="600" llx="105" lly="489" urx="503" ury="606"/> + <char name="trademark" width="600" llx="-23" lly="263" urx="623" ury="562"/> + <char name="two" width="600" llx="70" lly="0" urx="471" ury="622"/> + <char name="twosuperior" width="600" llx="177" lly="249" urx="424" ury="622"/> + <char name="u" width="600" llx="21" lly="-15" urx="562" ury="426"/> + <char name="uacute" width="600" llx="21" lly="-15" urx="562" ury="672"/> + <char name="ucircumflex" width="600" llx="21" lly="-15" urx="562" ury="654"/> + <char name="udieresis" width="600" llx="21" lly="-15" urx="562" ury="620"/> + <char name="ugrave" width="600" llx="21" lly="-15" urx="562" ury="672"/> + <char name="underscore" width="600" llx="0" lly="-125" urx="600" ury="-75"/> + <char name="v" width="600" llx="10" lly="-10" urx="590" ury="426"/> + <char name="w" width="600" llx="-4" lly="-10" urx="604" ury="426"/> + <char name="x" width="600" llx="20" lly="0" urx="580" ury="426"/> + <char name="y" width="600" llx="7" lly="-157" urx="592" ury="426"/> + <char name="yacute" width="600" llx="7" lly="-157" urx="592" ury="672"/> + <char name="ydieresis" width="600" llx="7" lly="-157" urx="592" ury="620"/> + <char name="yen" width="600" llx="26" lly="0" urx="574" ury="562"/> + <char name="z" width="600" llx="99" lly="0" urx="502" ury="426"/> + <char name="zcaron" width="600" llx="99" lly="0" urx="502" ury="669"/> + <char name="zero" width="600" llx="106" lly="-15" urx="494" ury="622"/> + </char-metrics> +</font-metrics> diff --git a/src/codegen/fonts/CourierBold.xml b/src/codegen/fonts/CourierBold.xml index fa8bed196..c06ef5f23 100644 --- a/src/codegen/fonts/CourierBold.xml +++ b/src/codegen/fonts/CourierBold.xml @@ -22,275 +22,246 @@ <family-name>Courier</family-name> <class-name>CourierBold</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>562</cap-height> <x-height>439</x-height> <ascender>626</ascender> <descender>-142</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="600"/> - <char name="AE" width="600"/> - <char name="Aacute" width="600"/> - <char name="Acircumflex" width="600"/> - <char name="Adieresis" width="600"/> - <char name="Agrave" width="600"/> - <char name="Aring" width="600"/> - <char name="Atilde" width="600"/> - <char name="B" width="600"/> - <char name="C" width="600"/> - <char name="Ccedilla" width="600"/> - <char name="D" width="600"/> - <char name="E" width="600"/> - <char name="Eacute" width="600"/> - <char name="Ecircumflex" width="600"/> - <char name="Edieresis" width="600"/> - <char name="Egrave" width="600"/> - <char name="Eth" width="600"/> - <char name="Euro" width="600"/> - <char name="F" width="600"/> - <char name="G" width="600"/> - <char name="Gcaron" width="600"/> - <char name="H" width="600"/> - <char name="I" width="600"/> - <char name="IJ" width="600"/> - <char name="Iacute" width="600"/> - <char name="Icircumflex" width="600"/> - <char name="Idieresis" width="600"/> - <char name="Idot" width="600"/> - <char name="Igrave" width="600"/> - <char name="J" width="600"/> - <char name="K" width="600"/> - <char name="L" width="600"/> - <char name="LL" width="600"/> - <char name="Lslash" width="600"/> - <char name="M" width="600"/> - <char name="N" width="600"/> - <char name="Ntilde" width="600"/> - <char name="O" width="600"/> - <char name="OE" width="600"/> - <char name="Oacute" width="600"/> - <char name="Ocircumflex" width="600"/> - <char name="Odieresis" width="600"/> - <char name="Ograve" width="600"/> - <char name="Oslash" width="600"/> - <char name="Otilde" width="600"/> - <char name="P" width="600"/> - <char name="Q" width="600"/> - <char name="R" width="600"/> - <char name="S" width="600"/> - <char name="Scaron" width="600"/> - <char name="Scedilla" width="600"/> - <char name="T" width="600"/> - <char name="Thorn" width="600"/> - <char name="U" width="600"/> - <char name="Uacute" width="600"/> - <char name="Ucircumflex" width="600"/> - <char name="Udieresis" width="600"/> - <char name="Ugrave" width="600"/> - <char name="V" width="600"/> - <char name="W" width="600"/> - <char name="X" width="600"/> - <char name="Y" width="600"/> - <char name="Yacute" width="600"/> - <char name="Ydieresis" width="600"/> - <char name="Z" width="600"/> - <char name="Zcaron" width="600"/> - <char name="a" width="600"/> - <char name="aacute" width="600"/> - <char name="acircumflex" width="600"/> - <char name="acute" width="600"/> - <char name="adieresis" width="600"/> - <char name="ae" width="600"/> - <char name="agrave" width="600"/> - <char name="ampersand" width="600"/> - <char name="aring" width="600"/> - <char name="arrowboth" width="600"/> - <char name="arrowdown" width="600"/> - <char name="arrowleft" width="600"/> - <char name="arrowright" width="600"/> - <char name="arrowup" width="600"/> - <char name="asciicircum" width="600"/> - <char name="asciitilde" width="600"/> - <char name="asterisk" width="600"/> - <char name="at" width="600"/> - <char name="atilde" width="600"/> - <char name="b" width="600"/> - <char name="backslash" width="600"/> - <char name="bar" width="600"/> - <char name="braceleft" width="600"/> - <char name="braceright" width="600"/> - <char name="bracketleft" width="600"/> - <char name="bracketright" width="600"/> - <char name="breve" width="600"/> - <char name="brokenbar" width="600"/> - <char name="bullet" width="600"/> - <char name="c" width="600"/> - <char name="caron" width="600"/> - <char name="ccedilla" width="600"/> - <char name="cedilla" width="600"/> - <char name="cent" width="600"/> - <char name="center" width="600"/> - <char name="circumflex" width="600"/> - <char name="colon" width="600"/> - <char name="comma" width="600"/> - <char name="copyright" width="600"/> - <char name="currency" width="600"/> - <char name="d" width="600"/> - <char name="dagger" width="600"/> - <char name="daggerdbl" width="600"/> - <char name="dectab" width="600"/> - <char name="degree" width="600"/> - <char name="dieresis" width="600"/> - <char name="divide" width="600"/> - <char name="dollar" width="600"/> - <char name="dotaccent" width="600"/> - <char name="dotlessi" width="600"/> - <char name="down" width="600"/> - <char name="e" width="600"/> - <char name="eacute" width="600"/> - <char name="ecircumflex" width="600"/> - <char name="edieresis" width="600"/> - <char name="egrave" width="600"/> - <char name="eight" width="600"/> - <char name="ellipsis" width="600"/> - <char name="emdash" width="600"/> - <char name="endash" width="600"/> - <char name="equal" width="600"/> - <char name="eth" width="600"/> - <char name="exclam" width="600"/> - <char name="exclamdown" width="600"/> - <char name="f" width="600"/> - <char name="fi" width="600"/> - <char name="five" width="600"/> - <char name="fl" width="600"/> - <char name="florin" width="600"/> - <char name="format" width="600"/> - <char name="four" width="600"/> - <char name="fraction" width="600"/> - <char name="g" width="600"/> - <char name="gcaron" width="600"/> - <char name="germandbls" width="600"/> - <char name="grave" width="600"/> - <char name="graybox" width="600"/> - <char name="greater" width="600"/> - <char name="guillemotleft" width="600"/> - <char name="guillemotright" width="600"/> - <char name="guilsinglleft" width="600"/> - <char name="guilsinglright" width="600"/> - <char name="h" width="600"/> - <char name="hungarumlaut" width="600"/> - <char name="hyphen" width="600"/> - <char name="i" width="600"/> - <char name="iacute" width="600"/> - <char name="icircumflex" width="600"/> - <char name="idieresis" width="600"/> - <char name="igrave" width="600"/> - <char name="ij" width="600"/> - <char name="indent" width="600"/> - <char name="j" width="600"/> - <char name="k" width="600"/> - <char name="l" width="600"/> - <char name="largebullet" width="600"/> - <char name="left" width="600"/> - <char name="less" width="600"/> - <char name="lira" width="600"/> - <char name="ll" width="600"/> - <char name="logicalnot" width="600"/> - <char name="lslash" width="600"/> - <char name="m" width="600"/> - <char name="macron" width="600"/> - <char name="merge" width="600"/> - <char name="minus" width="600"/> - <char name="mu" width="600"/> - <char name="multiply" width="600"/> - <char name="n" width="600"/> - <char name="nine" width="600"/> - <char name="notegraphic" width="600"/> - <char name="ntilde" width="600"/> - <char name="numbersign" width="600"/> - <char name="o" width="600"/> - <char name="oacute" width="600"/> - <char name="ocircumflex" width="600"/> - <char name="odieresis" width="600"/> - <char name="oe" width="600"/> - <char name="ogonek" width="600"/> - <char name="ograve" width="600"/> - <char name="one" width="600"/> - <char name="onehalf" width="600"/> - <char name="onequarter" width="600"/> - <char name="onesuperior" width="600"/> - <char name="ordfeminine" width="600"/> - <char name="ordmasculine" width="600"/> - <char name="oslash" width="600"/> - <char name="otilde" width="600"/> - <char name="overscore" width="600"/> - <char name="p" width="600"/> - <char name="paragraph" width="600"/> - <char name="parenleft" width="600"/> - <char name="parenright" width="600"/> - <char name="percent" width="600"/> - <char name="period" width="600"/> - <char name="periodcentered" width="600"/> - <char name="perthousand" width="600"/> - <char name="plus" width="600"/> - <char name="plusminus" width="600"/> - <char name="prescription" width="600"/> - <char name="q" width="600"/> - <char name="question" width="600"/> - <char name="questiondown" width="600"/> - <char name="quotedbl" width="600"/> - <char name="quotedblbase" width="600"/> - <char name="quotedblleft" width="600"/> - <char name="quotedblright" width="600"/> - <char name="quoteleft" width="600"/> - <char name="quoteright" width="600"/> - <char name="quotesinglbase" width="600"/> - <char name="quotesingle" width="600"/> - <char name="r" width="600"/> - <char name="registered" width="600"/> - <char name="return" width="600"/> - <char name="ring" width="600"/> - <char name="s" width="600"/> - <char name="scaron" width="600"/> - <char name="scedilla" width="600"/> - <char name="section" width="600"/> - <char name="semicolon" width="600"/> - <char name="seven" width="600"/> - <char name="six" width="600"/> - <char name="slash" width="600"/> - <char name="space" width="600"/> + <char-metrics> + <char name="A" width="600" llx="-9" lly="0" urx="609" ury="562"/> + <char name="AE" width="600" llx="-29" lly="0" urx="602" ury="562"/> + <char name="Aacute" width="600" llx="-9" lly="0" urx="609" ury="784"/> + <char name="Acircumflex" width="600" llx="-9" lly="0" urx="609" ury="780"/> + <char name="Adieresis" width="600" llx="-9" lly="0" urx="609" ury="761"/> + <char name="Agrave" width="600" llx="-9" lly="0" urx="609" ury="784"/> + <char name="Aring" width="600" llx="-9" lly="0" urx="609" ury="801"/> + <char name="Atilde" width="600" llx="-9" lly="0" urx="609" ury="759"/> + <char name="B" width="600" llx="30" lly="0" urx="573" ury="562"/> + <char name="C" width="600" llx="22" lly="-18" urx="560" ury="580"/> + <char name="Ccedilla" width="600" llx="22" lly="-206" urx="560" ury="580"/> + <char name="D" width="600" llx="30" lly="0" urx="594" ury="562"/> + <char name="E" width="600" llx="25" lly="0" urx="560" ury="562"/> + <char name="Eacute" width="600" llx="25" lly="0" urx="560" ury="784"/> + <char name="Ecircumflex" width="600" llx="25" lly="0" urx="560" ury="780"/> + <char name="Edieresis" width="600" llx="25" lly="0" urx="560" ury="761"/> + <char name="Egrave" width="600" llx="25" lly="0" urx="560" ury="784"/> + <char name="Eth" width="600" llx="30" lly="0" urx="594" ury="562"/> + <char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="600" llx="39" lly="0" urx="570" ury="562"/> + <char name="G" width="600" llx="22" lly="-18" urx="594" ury="580"/> + <char name="H" width="600" llx="20" lly="0" urx="580" ury="562"/> + <char name="I" width="600" llx="77" lly="0" urx="523" ury="562"/> + <char name="Iacute" width="600" llx="77" lly="0" urx="523" ury="784"/> + <char name="Icircumflex" width="600" llx="77" lly="0" urx="523" ury="780"/> + <char name="Idieresis" width="600" llx="77" lly="0" urx="523" ury="761"/> + <char name="Igrave" width="600" llx="77" lly="0" urx="523" ury="784"/> + <char name="J" width="600" llx="37" lly="-18" urx="601" ury="562"/> + <char name="K" width="600" llx="21" lly="0" urx="599" ury="562"/> + <char name="L" width="600" llx="39" lly="0" urx="578" ury="562"/> + <char name="Lslash" width="600" llx="39" lly="0" urx="578" ury="562"/> + <char name="M" width="600" llx="-2" lly="0" urx="602" ury="562"/> + <char name="N" width="600" llx="8" lly="-12" urx="610" ury="562"/> + <char name="Ntilde" width="600" llx="8" lly="-12" urx="610" ury="759"/> + <char name="O" width="600" llx="22" lly="-18" urx="578" ury="580"/> + <char name="OE" width="600" llx="-25" lly="0" urx="595" ury="562"/> + <char name="Oacute" width="600" llx="22" lly="-18" urx="578" ury="784"/> + <char name="Ocircumflex" width="600" llx="22" lly="-18" urx="578" ury="780"/> + <char name="Odieresis" width="600" llx="22" lly="-18" urx="578" ury="761"/> + <char name="Ograve" width="600" llx="22" lly="-18" urx="578" ury="784"/> + <char name="Oslash" width="600" llx="22" lly="-22" urx="578" ury="584"/> + <char name="Otilde" width="600" llx="22" lly="-18" urx="578" ury="759"/> + <char name="P" width="600" llx="48" lly="0" urx="559" ury="562"/> + <char name="Q" width="600" llx="32" lly="-138" urx="578" ury="580"/> + <char name="R" width="600" llx="24" lly="0" urx="599" ury="562"/> + <char name="S" width="600" llx="47" lly="-22" urx="553" ury="582"/> + <char name="Scaron" width="600" llx="47" lly="-22" urx="553" ury="790"/> + <char name="Scedilla" width="600" llx="47" lly="-206" urx="553" ury="582"/> + <char name="T" width="600" llx="21" lly="0" urx="579" ury="562"/> + <char name="Thorn" width="600" llx="48" lly="0" urx="557" ury="562"/> + <char name="U" width="600" llx="4" lly="-18" urx="596" ury="562"/> + <char name="Uacute" width="600" llx="4" lly="-18" urx="596" ury="784"/> + <char name="Ucircumflex" width="600" llx="4" lly="-18" urx="596" ury="780"/> + <char name="Udieresis" width="600" llx="4" lly="-18" urx="596" ury="761"/> + <char name="Ugrave" width="600" llx="4" lly="-18" urx="596" ury="784"/> + <char name="V" width="600" llx="-13" lly="0" urx="613" ury="562"/> + <char name="W" width="600" llx="-18" lly="0" urx="618" ury="562"/> + <char name="X" width="600" llx="12" lly="0" urx="588" ury="562"/> + <char name="Y" width="600" llx="12" lly="0" urx="589" ury="562"/> + <char name="Yacute" width="600" llx="12" lly="0" urx="589" ury="784"/> + <char name="Ydieresis" width="600" llx="12" lly="0" urx="589" ury="761"/> + <char name="Z" width="600" llx="62" lly="0" urx="539" ury="562"/> + <char name="Zcaron" width="600" llx="62" lly="0" urx="539" ury="790"/> + <char name="a" width="600" llx="35" lly="-15" urx="570" ury="454"/> + <char name="aacute" width="600" llx="35" lly="-15" urx="570" ury="661"/> + <char name="acircumflex" width="600" llx="35" lly="-15" urx="570" ury="657"/> + <char name="acute" width="600" llx="205" lly="508" urx="468" ury="661"/> + <char name="adieresis" width="600" llx="35" lly="-15" urx="570" ury="638"/> + <char name="ae" width="600" llx="-4" lly="-15" urx="601" ury="454"/> + <char name="agrave" width="600" llx="35" lly="-15" urx="570" ury="661"/> + <char name="ampersand" width="600" llx="36" lly="-15" urx="546" ury="543"/> + <char name="aring" width="600" llx="35" lly="-15" urx="570" ury="678"/> + <char name="asciicircum" width="600" llx="108" lly="250" urx="492" ury="616"/> + <char name="asciitilde" width="600" llx="71" lly="153" urx="530" ury="356"/> + <char name="asterisk" width="600" llx="91" lly="219" urx="509" ury="601"/> + <char name="at" width="600" llx="16" lly="-15" urx="584" ury="616"/> + <char name="atilde" width="600" llx="35" lly="-15" urx="570" ury="636"/> + <char name="b" width="600" llx="0" lly="-15" urx="584" ury="626"/> + <char name="backslash" width="600" llx="99" lly="-77" urx="503" ury="626"/> + <char name="bar" width="600" llx="255" lly="-250" urx="345" ury="750"/> + <char name="braceleft" width="600" llx="160" lly="-102" urx="464" ury="616"/> + <char name="braceright" width="600" llx="136" lly="-102" urx="440" ury="616"/> + <char name="bracketleft" width="600" llx="245" lly="-102" urx="475" ury="616"/> + <char name="bracketright" width="600" llx="125" lly="-102" urx="355" ury="616"/> + <char name="breve" width="600" llx="83" lly="468" urx="517" ury="631"/> + <char name="brokenbar" width="600" llx="255" lly="-175" urx="345" ury="675"/> + <char name="bullet" width="600" llx="140" lly="132" urx="460" ury="430"/> + <char name="c" width="600" llx="40" lly="-15" urx="545" ury="459"/> + <char name="caron" width="600" llx="103" lly="493" urx="497" ury="667"/> + <char name="ccedilla" width="600" llx="40" lly="-206" urx="545" ury="459"/> + <char name="cedilla" width="600" llx="205" lly="-206" urx="387" ury="0"/> + <char name="cent" width="600" llx="66" lly="-49" urx="518" ury="614"/> + <char name="circumflex" width="600" llx="103" lly="483" urx="497" ury="657"/> + <char name="colon" width="600" llx="191" lly="-15" urx="407" ury="425"/> + <char name="comma" width="600" llx="123" lly="-111" urx="393" ury="174"/> + <char name="copyright" width="600" llx="0" lly="-18" urx="600" ury="580"/> + <char name="currency" width="600" llx="54" lly="49" urx="546" ury="517"/> + <char name="d" width="600" llx="20" lly="-15" urx="591" ury="626"/> + <char name="dagger" width="600" llx="106" lly="-70" urx="494" ury="580"/> + <char name="daggerdbl" width="600" llx="106" lly="-70" urx="494" ury="580"/> + <char name="degree" width="600" llx="86" lly="243" urx="474" ury="616"/> + <char name="dieresis" width="600" llx="128" lly="498" urx="472" ury="638"/> + <char name="divide" width="600" llx="71" lly="16" urx="529" ury="500"/> + <char name="dollar" width="600" llx="82" lly="-126" urx="519" ury="666"/> + <char name="dotaccent" width="600" llx="230" lly="498" urx="370" ury="638"/> + <char name="dotlessi" width="600" llx="77" lly="0" urx="523" ury="439"/> + <char name="e" width="600" llx="40" lly="-15" urx="563" ury="454"/> + <char name="eacute" width="600" llx="40" lly="-15" urx="563" ury="661"/> + <char name="ecircumflex" width="600" llx="40" lly="-15" urx="563" ury="657"/> + <char name="edieresis" width="600" llx="40" lly="-15" urx="563" ury="638"/> + <char name="egrave" width="600" llx="40" lly="-15" urx="563" ury="661"/> + <char name="eight" width="600" llx="83" lly="-15" urx="517" ury="616"/> + <char name="ellipsis" width="600" llx="26" lly="-15" urx="574" ury="116"/> + <char name="emdash" width="600" llx="-10" lly="203" urx="610" ury="313"/> + <char name="endash" width="600" llx="65" lly="203" urx="535" ury="313"/> + <char name="equal" width="600" llx="71" lly="118" urx="529" ury="398"/> + <char name="eth" width="600" llx="58" lly="-27" urx="543" ury="626"/> + <char name="exclam" width="600" llx="202" lly="-15" urx="398" ury="572"/> + <char name="exclamdown" width="600" llx="202" lly="-146" urx="398" ury="449"/> + <char name="f" width="600" llx="83" lly="0" urx="547" ury="626"/> + <char name="fi" width="600" llx="12" lly="0" urx="593" ury="626"/> + <char name="five" width="600" llx="70" lly="-15" urx="521" ury="601"/> + <char name="fl" width="600" llx="12" lly="0" urx="593" ury="626"/> + <char name="florin" width="600" llx="-30" lly="-131" urx="572" ury="616"/> + <char name="four" width="600" llx="53" lly="0" urx="507" ury="616"/> + <char name="fraction" width="600" llx="25" lly="-60" urx="576" ury="661"/> + <char name="g" width="600" llx="30" lly="-146" urx="580" ury="454"/> + <char name="germandbls" width="600" llx="22" lly="-15" urx="596" ury="626"/> + <char name="grave" width="600" llx="132" lly="508" urx="395" ury="661"/> + <char name="greater" width="600" llx="77" lly="15" urx="534" ury="501"/> + <char name="guillemotleft" width="600" llx="8" lly="70" urx="553" ury="446"/> + <char name="guillemotright" width="600" llx="47" lly="70" urx="592" ury="446"/> + <char name="guilsinglleft" width="600" llx="141" lly="70" urx="459" ury="446"/> + <char name="guilsinglright" width="600" llx="141" lly="70" urx="459" ury="446"/> + <char name="h" width="600" llx="5" lly="0" urx="592" ury="626"/> + <char name="hungarumlaut" width="600" llx="68" lly="488" urx="588" ury="661"/> + <char name="hyphen" width="600" llx="100" lly="203" urx="500" ury="313"/> + <char name="i" width="600" llx="77" lly="0" urx="523" ury="658"/> + <char name="iacute" width="600" llx="77" lly="0" urx="523" ury="661"/> + <char name="icircumflex" width="600" llx="73" lly="0" urx="523" ury="657"/> + <char name="idieresis" width="600" llx="77" lly="0" urx="523" ury="618"/> + <char name="igrave" width="600" llx="77" lly="0" urx="523" ury="661"/> + <char name="j" width="600" llx="63" lly="-146" urx="440" ury="658"/> + <char name="k" width="600" llx="20" lly="0" urx="585" ury="626"/> + <char name="l" width="600" llx="77" lly="0" urx="523" ury="626"/> + <char name="less" width="600" llx="66" lly="15" urx="523" ury="501"/> + <char name="logicalnot" width="600" llx="71" lly="103" urx="529" ury="413"/> + <char name="lslash" width="600" llx="77" lly="0" urx="523" ury="626"/> + <char name="m" width="600" llx="-22" lly="0" urx="626" ury="454"/> + <char name="macron" width="600" llx="88" lly="505" urx="512" ury="585"/> + <char name="minus" width="600" llx="71" lly="203" urx="529" ury="313"/> + <char name="mu" width="600" llx="-1" lly="-142" urx="569" ury="439"/> + <char name="multiply" width="600" llx="81" lly="39" urx="520" ury="478"/> + <char name="n" width="600" llx="18" lly="0" urx="592" ury="454"/> + <char name="nine" width="600" llx="79" lly="-15" urx="510" ury="616"/> + <char name="ntilde" width="600" llx="18" lly="0" urx="592" ury="636"/> + <char name="numbersign" width="600" llx="56" lly="-45" urx="544" ury="651"/> + <char name="o" width="600" llx="30" lly="-15" urx="570" ury="454"/> + <char name="oacute" width="600" llx="30" lly="-15" urx="570" ury="661"/> + <char name="ocircumflex" width="600" llx="30" lly="-15" urx="570" ury="657"/> + <char name="odieresis" width="600" llx="30" lly="-15" urx="570" ury="638"/> + <char name="oe" width="600" llx="-18" lly="-15" urx="611" ury="454"/> + <char name="ogonek" width="600" llx="169" lly="-199" urx="400" ury="0"/> + <char name="ograve" width="600" llx="30" lly="-15" urx="570" ury="661"/> + <char name="one" width="600" llx="81" lly="0" urx="539" ury="616"/> + <char name="onehalf" width="600" llx="-47" lly="-60" urx="648" ury="661"/> + <char name="onequarter" width="600" llx="-56" lly="-60" urx="656" ury="661"/> + <char name="onesuperior" width="600" llx="153" lly="230" urx="447" ury="616"/> + <char name="ordfeminine" width="600" llx="147" lly="196" urx="453" ury="580"/> + <char name="ordmasculine" width="600" llx="147" lly="196" urx="453" ury="580"/> + <char name="oslash" width="600" llx="30" lly="-24" urx="570" ury="463"/> + <char name="otilde" width="600" llx="30" lly="-15" urx="570" ury="636"/> + <char name="p" width="600" llx="-1" lly="-142" urx="570" ury="454"/> + <char name="paragraph" width="600" llx="6" lly="-70" urx="576" ury="580"/> + <char name="parenleft" width="600" llx="219" lly="-102" urx="461" ury="616"/> + <char name="parenright" width="600" llx="139" lly="-102" urx="381" ury="616"/> + <char name="percent" width="600" llx="5" lly="-15" urx="595" ury="616"/> + <char name="period" width="600" llx="192" lly="-15" urx="408" ury="171"/> + <char name="periodcentered" width="600" llx="196" lly="165" urx="404" ury="351"/> + <char name="perthousand" width="600" llx="-113" lly="-15" urx="713" ury="616"/> + <char name="plus" width="600" llx="71" lly="39" urx="529" ury="478"/> + <char name="plusminus" width="600" llx="71" lly="24" urx="529" ury="515"/> + <char name="q" width="600" llx="20" lly="-142" urx="591" ury="454"/> + <char name="question" width="600" llx="98" lly="-14" urx="501" ury="580"/> + <char name="questiondown" width="600" llx="99" lly="-146" urx="502" ury="449"/> + <char name="quotedbl" width="600" llx="135" lly="277" urx="465" ury="562"/> + <char name="quotedblbase" width="600" llx="65" lly="-142" urx="529" ury="143"/> + <char name="quotedblleft" width="600" llx="71" lly="277" urx="535" ury="562"/> + <char name="quotedblright" width="600" llx="61" lly="277" urx="525" ury="562"/> + <char name="quoteleft" width="600" llx="178" lly="277" urx="428" ury="562"/> + <char name="quoteright" width="600" llx="171" lly="277" urx="423" ury="562"/> + <char name="quotesinglbase" width="600" llx="175" lly="-142" urx="427" ury="143"/> + <char name="quotesingle" width="600" llx="227" lly="277" urx="373" ury="562"/> + <char name="r" width="600" llx="47" lly="0" urx="580" ury="454"/> + <char name="registered" width="600" llx="0" lly="-18" urx="600" ury="580"/> + <char name="ring" width="600" llx="198" lly="481" urx="402" ury="678"/> + <char name="s" width="600" llx="68" lly="-17" urx="535" ury="459"/> + <char name="scaron" width="600" llx="68" lly="-17" urx="535" ury="667"/> + <char name="scedilla" width="600" llx="68" lly="-206" urx="535" ury="459"/> + <char name="section" width="600" llx="83" lly="-70" urx="517" ury="580"/> + <char name="semicolon" width="600" llx="123" lly="-111" urx="408" ury="425"/> + <char name="seven" width="600" llx="55" lly="0" urx="494" ury="601"/> + <char name="six" width="600" llx="90" lly="-15" urx="521" ury="616"/> + <char name="slash" width="600" llx="98" lly="-77" urx="502" ury="626"/> + <char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="600"/> - <char name="square" width="600"/> - <char name="sterling" width="600"/> - <char name="stop" width="600"/> - <char name="t" width="600"/> - <char name="tab" width="600"/> - <char name="thorn" width="600"/> - <char name="three" width="600"/> - <char name="threequarters" width="600"/> - <char name="threesuperior" width="600"/> - <char name="tilde" width="600"/> - <char name="trademark" width="600"/> - <char name="two" width="600"/> - <char name="twosuperior" width="600"/> - <char name="u" width="600"/> - <char name="uacute" width="600"/> - <char name="ucircumflex" width="600"/> - <char name="udieresis" width="600"/> - <char name="ugrave" width="600"/> - <char name="underscore" width="600"/> - <char name="up" width="600"/> - <char name="v" width="600"/> - <char name="w" width="600"/> - <char name="x" width="600"/> - <char name="y" width="600"/> - <char name="yacute" width="600"/> - <char name="ydieresis" width="600"/> - <char name="yen" width="600"/> - <char name="z" width="600"/> - <char name="zcaron" width="600"/> - <char name="zero" width="600"/> - </widths> -</font-metrics>
\ No newline at end of file + <char name="sterling" width="600" llx="72" lly="-28" urx="558" ury="611"/> + <char name="t" width="600" llx="47" lly="-15" urx="532" ury="562"/> + <char name="thorn" width="600" llx="-14" lly="-142" urx="570" ury="626"/> + <char name="three" width="600" llx="63" lly="-15" urx="501" ury="616"/> + <char name="threequarters" width="600" llx="-47" lly="-60" urx="648" ury="661"/> + <char name="threesuperior" width="600" llx="138" lly="222" urx="433" ury="616"/> + <char name="tilde" width="600" llx="89" lly="493" urx="512" ury="636"/> + <char name="trademark" width="600" llx="-9" lly="230" urx="749" ury="562"/> + <char name="two" width="600" llx="61" lly="0" urx="499" ury="616"/> + <char name="twosuperior" width="600" llx="143" lly="230" urx="436" ury="616"/> + <char name="u" width="600" llx="-1" lly="-15" urx="569" ury="439"/> + <char name="uacute" width="600" llx="-1" lly="-15" urx="569" ury="661"/> + <char name="ucircumflex" width="600" llx="-1" lly="-15" urx="569" ury="657"/> + <char name="udieresis" width="600" llx="-1" lly="-15" urx="569" ury="638"/> + <char name="ugrave" width="600" llx="-1" lly="-15" urx="569" ury="661"/> + <char name="underscore" width="600" llx="0" lly="-125" urx="600" ury="-75"/> + <char name="v" width="600" llx="-1" lly="0" urx="601" ury="439"/> + <char name="w" width="600" llx="-18" lly="0" urx="618" ury="439"/> + <char name="x" width="600" llx="6" lly="0" urx="594" ury="439"/> + <char name="y" width="600" llx="-4" lly="-142" urx="601" ury="439"/> + <char name="yacute" width="600" llx="-4" lly="-142" urx="601" ury="661"/> + <char name="ydieresis" width="600" llx="-4" lly="-142" urx="601" ury="638"/> + <char name="yen" width="600" llx="10" lly="0" urx="590" ury="562"/> + <char name="z" width="600" llx="81" lly="0" urx="520" ury="439"/> + <char name="zcaron" width="600" llx="81" lly="0" urx="520" ury="667"/> + <char name="zero" width="600" llx="87" lly="-15" urx="513" ury="616"/> + </char-metrics> +</font-metrics> diff --git a/src/codegen/fonts/CourierBoldOblique.xml b/src/codegen/fonts/CourierBoldOblique.xml index 5bd26092e..a82a75ad2 100644 --- a/src/codegen/fonts/CourierBoldOblique.xml +++ b/src/codegen/fonts/CourierBoldOblique.xml @@ -22,275 +22,246 @@ <family-name>Courier</family-name> <class-name>CourierBoldOblique</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>562</cap-height> <x-height>439</x-height> <ascender>626</ascender> <descender>-142</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="600"/> - <char name="AE" width="600"/> - <char name="Aacute" width="600"/> - <char name="Acircumflex" width="600"/> - <char name="Adieresis" width="600"/> - <char name="Agrave" width="600"/> - <char name="Aring" width="600"/> - <char name="Atilde" width="600"/> - <char name="B" width="600"/> - <char name="C" width="600"/> - <char name="Ccedilla" width="600"/> - <char name="D" width="600"/> - <char name="E" width="600"/> - <char name="Eacute" width="600"/> - <char name="Ecircumflex" width="600"/> - <char name="Edieresis" width="600"/> - <char name="Egrave" width="600"/> - <char name="Eth" width="600"/> - <char name="Euro" width="600"/> - <char name="F" width="600"/> - <char name="G" width="600"/> - <char name="Gcaron" width="600"/> - <char name="H" width="600"/> - <char name="I" width="600"/> - <char name="IJ" width="600"/> - <char name="Iacute" width="600"/> - <char name="Icircumflex" width="600"/> - <char name="Idieresis" width="600"/> - <char name="Idot" width="600"/> - <char name="Igrave" width="600"/> - <char name="J" width="600"/> - <char name="K" width="600"/> - <char name="L" width="600"/> - <char name="LL" width="600"/> - <char name="Lslash" width="600"/> - <char name="M" width="600"/> - <char name="N" width="600"/> - <char name="Ntilde" width="600"/> - <char name="O" width="600"/> - <char name="OE" width="600"/> - <char name="Oacute" width="600"/> - <char name="Ocircumflex" width="600"/> - <char name="Odieresis" width="600"/> - <char name="Ograve" width="600"/> - <char name="Oslash" width="600"/> - <char name="Otilde" width="600"/> - <char name="P" width="600"/> - <char name="Q" width="600"/> - <char name="R" width="600"/> - <char name="S" width="600"/> - <char name="Scaron" width="600"/> - <char name="Scedilla" width="600"/> - <char name="T" width="600"/> - <char name="Thorn" width="600"/> - <char name="U" width="600"/> - <char name="Uacute" width="600"/> - <char name="Ucircumflex" width="600"/> - <char name="Udieresis" width="600"/> - <char name="Ugrave" width="600"/> - <char name="V" width="600"/> - <char name="W" width="600"/> - <char name="X" width="600"/> - <char name="Y" width="600"/> - <char name="Yacute" width="600"/> - <char name="Ydieresis" width="600"/> - <char name="Z" width="600"/> - <char name="Zcaron" width="600"/> - <char name="a" width="600"/> - <char name="aacute" width="600"/> - <char name="acircumflex" width="600"/> - <char name="acute" width="600"/> - <char name="adieresis" width="600"/> - <char name="ae" width="600"/> - <char name="agrave" width="600"/> - <char name="ampersand" width="600"/> - <char name="aring" width="600"/> - <char name="arrowboth" width="600"/> - <char name="arrowdown" width="600"/> - <char name="arrowleft" width="600"/> - <char name="arrowright" width="600"/> - <char name="arrowup" width="600"/> - <char name="asciicircum" width="600"/> - <char name="asciitilde" width="600"/> - <char name="asterisk" width="600"/> - <char name="at" width="600"/> - <char name="atilde" width="600"/> - <char name="b" width="600"/> - <char name="backslash" width="600"/> - <char name="bar" width="600"/> - <char name="braceleft" width="600"/> - <char name="braceright" width="600"/> - <char name="bracketleft" width="600"/> - <char name="bracketright" width="600"/> - <char name="breve" width="600"/> - <char name="brokenbar" width="600"/> - <char name="bullet" width="600"/> - <char name="c" width="600"/> - <char name="caron" width="600"/> - <char name="ccedilla" width="600"/> - <char name="cedilla" width="600"/> - <char name="cent" width="600"/> - <char name="center" width="600"/> - <char name="circumflex" width="600"/> - <char name="colon" width="600"/> - <char name="comma" width="600"/> - <char name="copyright" width="600"/> - <char name="currency" width="600"/> - <char name="d" width="600"/> - <char name="dagger" width="600"/> - <char name="daggerdbl" width="600"/> - <char name="dectab" width="600"/> - <char name="degree" width="600"/> - <char name="dieresis" width="600"/> - <char name="divide" width="600"/> - <char name="dollar" width="600"/> - <char name="dotaccent" width="600"/> - <char name="dotlessi" width="600"/> - <char name="down" width="600"/> - <char name="e" width="600"/> - <char name="eacute" width="600"/> - <char name="ecircumflex" width="600"/> - <char name="edieresis" width="600"/> - <char name="egrave" width="600"/> - <char name="eight" width="600"/> - <char name="ellipsis" width="600"/> - <char name="emdash" width="600"/> - <char name="endash" width="600"/> - <char name="equal" width="600"/> - <char name="eth" width="600"/> - <char name="exclam" width="600"/> - <char name="exclamdown" width="600"/> - <char name="f" width="600"/> - <char name="fi" width="600"/> - <char name="five" width="600"/> - <char name="fl" width="600"/> - <char name="florin" width="600"/> - <char name="format" width="600"/> - <char name="four" width="600"/> - <char name="fraction" width="600"/> - <char name="g" width="600"/> - <char name="gcaron" width="600"/> - <char name="germandbls" width="600"/> - <char name="grave" width="600"/> - <char name="graybox" width="600"/> - <char name="greater" width="600"/> - <char name="guillemotleft" width="600"/> - <char name="guillemotright" width="600"/> - <char name="guilsinglleft" width="600"/> - <char name="guilsinglright" width="600"/> - <char name="h" width="600"/> - <char name="hungarumlaut" width="600"/> - <char name="hyphen" width="600"/> - <char name="i" width="600"/> - <char name="iacute" width="600"/> - <char name="icircumflex" width="600"/> - <char name="idieresis" width="600"/> - <char name="igrave" width="600"/> - <char name="ij" width="600"/> - <char name="indent" width="600"/> - <char name="j" width="600"/> - <char name="k" width="600"/> - <char name="l" width="600"/> - <char name="largebullet" width="600"/> - <char name="left" width="600"/> - <char name="less" width="600"/> - <char name="lira" width="600"/> - <char name="ll" width="600"/> - <char name="logicalnot" width="600"/> - <char name="lslash" width="600"/> - <char name="m" width="600"/> - <char name="macron" width="600"/> - <char name="merge" width="600"/> - <char name="minus" width="600"/> - <char name="mu" width="600"/> - <char name="multiply" width="600"/> - <char name="n" width="600"/> - <char name="nine" width="600"/> - <char name="notegraphic" width="600"/> - <char name="ntilde" width="600"/> - <char name="numbersign" width="600"/> - <char name="o" width="600"/> - <char name="oacute" width="600"/> - <char name="ocircumflex" width="600"/> - <char name="odieresis" width="600"/> - <char name="oe" width="600"/> - <char name="ogonek" width="600"/> - <char name="ograve" width="600"/> - <char name="one" width="600"/> - <char name="onehalf" width="600"/> - <char name="onequarter" width="600"/> - <char name="onesuperior" width="600"/> - <char name="ordfeminine" width="600"/> - <char name="ordmasculine" width="600"/> - <char name="oslash" width="600"/> - <char name="otilde" width="600"/> - <char name="overscore" width="600"/> - <char name="p" width="600"/> - <char name="paragraph" width="600"/> - <char name="parenleft" width="600"/> - <char name="parenright" width="600"/> - <char name="percent" width="600"/> - <char name="period" width="600"/> - <char name="periodcentered" width="600"/> - <char name="perthousand" width="600"/> - <char name="plus" width="600"/> - <char name="plusminus" width="600"/> - <char name="prescription" width="600"/> - <char name="q" width="600"/> - <char name="question" width="600"/> - <char name="questiondown" width="600"/> - <char name="quotedbl" width="600"/> - <char name="quotedblbase" width="600"/> - <char name="quotedblleft" width="600"/> - <char name="quotedblright" width="600"/> - <char name="quoteleft" width="600"/> - <char name="quoteright" width="600"/> - <char name="quotesinglbase" width="600"/> - <char name="quotesingle" width="600"/> - <char name="r" width="600"/> - <char name="registered" width="600"/> - <char name="return" width="600"/> - <char name="ring" width="600"/> - <char name="s" width="600"/> - <char name="scaron" width="600"/> - <char name="scedilla" width="600"/> - <char name="section" width="600"/> - <char name="semicolon" width="600"/> - <char name="seven" width="600"/> - <char name="six" width="600"/> - <char name="slash" width="600"/> - <char name="space" width="600"/> + <char-metrics> + <char name="A" width="600" llx="-9" lly="0" urx="632" ury="562"/> + <char name="AE" width="600" llx="-29" lly="0" urx="708" ury="562"/> + <char name="Aacute" width="600" llx="-9" lly="0" urx="655" ury="784"/> + <char name="Acircumflex" width="600" llx="-9" lly="0" urx="632" ury="780"/> + <char name="Adieresis" width="600" llx="-9" lly="0" urx="632" ury="761"/> + <char name="Agrave" width="600" llx="-9" lly="0" urx="632" ury="784"/> + <char name="Aring" width="600" llx="-9" lly="0" urx="632" ury="801"/> + <char name="Atilde" width="600" llx="-9" lly="0" urx="669" ury="759"/> + <char name="B" width="600" llx="30" lly="0" urx="630" ury="562"/> + <char name="C" width="600" llx="74" lly="-18" urx="675" ury="580"/> + <char name="Ccedilla" width="600" llx="74" lly="-206" urx="675" ury="580"/> + <char name="D" width="600" llx="30" lly="0" urx="664" ury="562"/> + <char name="E" width="600" llx="25" lly="0" urx="670" ury="562"/> + <char name="Eacute" width="600" llx="25" lly="0" urx="670" ury="784"/> + <char name="Ecircumflex" width="600" llx="25" lly="0" urx="670" ury="780"/> + <char name="Edieresis" width="600" llx="25" lly="0" urx="670" ury="761"/> + <char name="Egrave" width="600" llx="25" lly="0" urx="670" ury="784"/> + <char name="Eth" width="600" llx="30" lly="0" urx="664" ury="562"/> + <char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="600" llx="39" lly="0" urx="684" ury="562"/> + <char name="G" width="600" llx="74" lly="-18" urx="675" ury="580"/> + <char name="H" width="600" llx="20" lly="0" urx="700" ury="562"/> + <char name="I" width="600" llx="77" lly="0" urx="643" ury="562"/> + <char name="Iacute" width="600" llx="77" lly="0" urx="643" ury="784"/> + <char name="Icircumflex" width="600" llx="77" lly="0" urx="643" ury="780"/> + <char name="Idieresis" width="600" llx="77" lly="0" urx="643" ury="761"/> + <char name="Igrave" width="600" llx="77" lly="0" urx="643" ury="784"/> + <char name="J" width="600" llx="58" lly="-18" urx="721" ury="562"/> + <char name="K" width="600" llx="21" lly="0" urx="692" ury="562"/> + <char name="L" width="600" llx="39" lly="0" urx="636" ury="562"/> + <char name="Lslash" width="600" llx="39" lly="0" urx="636" ury="562"/> + <char name="M" width="600" llx="-2" lly="0" urx="722" ury="562"/> + <char name="N" width="600" llx="8" lly="-12" urx="730" ury="562"/> + <char name="Ntilde" width="600" llx="8" lly="-12" urx="730" ury="759"/> + <char name="O" width="600" llx="74" lly="-18" urx="645" ury="580"/> + <char name="OE" width="600" llx="26" lly="0" urx="701" ury="562"/> + <char name="Oacute" width="600" llx="74" lly="-18" urx="645" ury="784"/> + <char name="Ocircumflex" width="600" llx="74" lly="-18" urx="645" ury="780"/> + <char name="Odieresis" width="600" llx="74" lly="-18" urx="645" ury="761"/> + <char name="Ograve" width="600" llx="74" lly="-18" urx="645" ury="784"/> + <char name="Oslash" width="600" llx="48" lly="-22" urx="673" ury="584"/> + <char name="Otilde" width="600" llx="74" lly="-18" urx="669" ury="759"/> + <char name="P" width="600" llx="48" lly="0" urx="643" ury="562"/> + <char name="Q" width="600" llx="83" lly="-138" urx="636" ury="580"/> + <char name="R" width="600" llx="24" lly="0" urx="617" ury="562"/> + <char name="S" width="600" llx="54" lly="-22" urx="673" ury="582"/> + <char name="Scaron" width="600" llx="54" lly="-22" urx="689" ury="790"/> + <char name="Scedilla" width="600" llx="54" lly="-206" urx="673" ury="582"/> + <char name="T" width="600" llx="86" lly="0" urx="679" ury="562"/> + <char name="Thorn" width="600" llx="48" lly="0" urx="620" ury="562"/> + <char name="U" width="600" llx="101" lly="-18" urx="716" ury="562"/> + <char name="Uacute" width="600" llx="101" lly="-18" urx="716" ury="784"/> + <char name="Ucircumflex" width="600" llx="101" lly="-18" urx="716" ury="780"/> + <char name="Udieresis" width="600" llx="101" lly="-18" urx="716" ury="761"/> + <char name="Ugrave" width="600" llx="101" lly="-18" urx="716" ury="784"/> + <char name="V" width="600" llx="84" lly="0" urx="733" ury="562"/> + <char name="W" width="600" llx="79" lly="0" urx="738" ury="562"/> + <char name="X" width="600" llx="12" lly="0" urx="690" ury="562"/> + <char name="Y" width="600" llx="109" lly="0" urx="709" ury="562"/> + <char name="Yacute" width="600" llx="109" lly="0" urx="709" ury="784"/> + <char name="Ydieresis" width="600" llx="109" lly="0" urx="709" ury="761"/> + <char name="Z" width="600" llx="62" lly="0" urx="637" ury="562"/> + <char name="Zcaron" width="600" llx="62" lly="0" urx="659" ury="790"/> + <char name="a" width="600" llx="61" lly="-15" urx="593" ury="454"/> + <char name="aacute" width="600" llx="61" lly="-15" urx="609" ury="661"/> + <char name="acircumflex" width="600" llx="61" lly="-15" urx="607" ury="657"/> + <char name="acute" width="600" llx="312" lly="508" urx="609" ury="661"/> + <char name="adieresis" width="600" llx="61" lly="-15" urx="595" ury="638"/> + <char name="ae" width="600" llx="21" lly="-15" urx="652" ury="454"/> + <char name="agrave" width="600" llx="61" lly="-15" urx="593" ury="661"/> + <char name="ampersand" width="600" llx="61" lly="-15" urx="595" ury="543"/> + <char name="aring" width="600" llx="61" lly="-15" urx="593" ury="678"/> + <char name="asciicircum" width="600" llx="171" lly="250" urx="556" ury="616"/> + <char name="asciitilde" width="600" llx="120" lly="153" urx="590" ury="356"/> + <char name="asterisk" width="600" llx="179" lly="219" urx="598" ury="601"/> + <char name="at" width="600" llx="65" lly="-15" urx="642" ury="616"/> + <char name="atilde" width="600" llx="61" lly="-15" urx="643" ury="636"/> + <char name="b" width="600" llx="13" lly="-15" urx="636" ury="626"/> + <char name="backslash" width="600" llx="222" lly="-77" urx="496" ury="626"/> + <char name="bar" width="600" llx="201" lly="-250" urx="505" ury="750"/> + <char name="braceleft" width="600" llx="203" lly="-102" urx="595" ury="616"/> + <char name="braceright" width="600" llx="114" lly="-102" urx="506" ury="616"/> + <char name="bracketleft" width="600" llx="223" lly="-102" urx="606" ury="616"/> + <char name="bracketright" width="600" llx="103" lly="-102" urx="486" ury="616"/> + <char name="breve" width="600" llx="217" lly="468" urx="652" ury="631"/> + <char name="brokenbar" width="600" llx="217" lly="-175" urx="489" ury="675"/> + <char name="bullet" width="600" llx="196" lly="132" urx="523" ury="430"/> + <char name="c" width="600" llx="81" lly="-15" urx="631" ury="459"/> + <char name="caron" width="600" llx="238" lly="493" urx="633" ury="667"/> + <char name="ccedilla" width="600" llx="81" lly="-206" urx="631" ury="459"/> + <char name="cedilla" width="600" llx="168" lly="-206" urx="368" ury="0"/> + <char name="cent" width="600" llx="121" lly="-49" urx="605" ury="614"/> + <char name="circumflex" width="600" llx="212" lly="483" urx="607" ury="657"/> + <char name="colon" width="600" llx="205" lly="-15" urx="480" ury="425"/> + <char name="comma" width="600" llx="99" lly="-111" urx="430" ury="174"/> + <char name="copyright" width="600" llx="53" lly="-18" urx="667" ury="580"/> + <char name="currency" width="600" llx="77" lly="49" urx="644" ury="517"/> + <char name="d" width="600" llx="60" lly="-15" urx="645" ury="626"/> + <char name="dagger" width="600" llx="175" lly="-70" urx="586" ury="580"/> + <char name="daggerdbl" width="600" llx="121" lly="-70" urx="587" ury="580"/> + <char name="degree" width="600" llx="173" lly="243" urx="570" ury="616"/> + <char name="dieresis" width="600" llx="246" lly="498" urx="595" ury="638"/> + <char name="divide" width="600" llx="114" lly="16" urx="596" ury="500"/> + <char name="dollar" width="600" llx="87" lly="-126" urx="630" ury="666"/> + <char name="dotaccent" width="600" llx="348" lly="498" urx="493" ury="638"/> + <char name="dotlessi" width="600" llx="77" lly="0" urx="546" ury="439"/> + <char name="e" width="600" llx="81" lly="-15" urx="605" ury="454"/> + <char name="eacute" width="600" llx="81" lly="-15" urx="609" ury="661"/> + <char name="ecircumflex" width="600" llx="81" lly="-15" urx="607" ury="657"/> + <char name="edieresis" width="600" llx="81" lly="-15" urx="605" ury="638"/> + <char name="egrave" width="600" llx="81" lly="-15" urx="605" ury="661"/> + <char name="eight" width="600" llx="115" lly="-15" urx="604" ury="616"/> + <char name="ellipsis" width="600" llx="35" lly="-15" urx="587" ury="116"/> + <char name="emdash" width="600" llx="33" lly="203" urx="677" ury="313"/> + <char name="endash" width="600" llx="108" lly="203" urx="602" ury="313"/> + <char name="equal" width="600" llx="96" lly="118" urx="614" ury="398"/> + <char name="eth" width="600" llx="93" lly="-27" urx="661" ury="626"/> + <char name="exclam" width="600" llx="215" lly="-15" urx="495" ury="572"/> + <char name="exclamdown" width="600" llx="196" lly="-146" urx="477" ury="449"/> + <char name="f" width="600" llx="83" lly="0" urx="677" ury="626"/> + <char name="fi" width="600" llx="12" lly="0" urx="644" ury="626"/> + <char name="five" width="600" llx="77" lly="-15" urx="621" ury="601"/> + <char name="fl" width="600" llx="12" lly="0" urx="644" ury="626"/> + <char name="florin" width="600" llx="-57" lly="-131" urx="702" ury="616"/> + <char name="four" width="600" llx="81" lly="0" urx="559" ury="616"/> + <char name="fraction" width="600" llx="22" lly="-60" urx="708" ury="661"/> + <char name="g" width="600" llx="40" lly="-146" urx="674" ury="454"/> + <char name="germandbls" width="600" llx="22" lly="-15" urx="629" ury="626"/> + <char name="grave" width="600" llx="272" lly="508" urx="503" ury="661"/> + <char name="greater" width="600" llx="97" lly="15" urx="589" ury="501"/> + <char name="guillemotleft" width="600" llx="62" lly="70" urx="639" ury="446"/> + <char name="guillemotright" width="600" llx="71" lly="70" urx="647" ury="446"/> + <char name="guilsinglleft" width="600" llx="195" lly="70" urx="545" ury="446"/> + <char name="guilsinglright" width="600" llx="165" lly="70" urx="514" ury="446"/> + <char name="h" width="600" llx="18" lly="0" urx="615" ury="626"/> + <char name="hungarumlaut" width="600" llx="171" lly="488" urx="729" ury="661"/> + <char name="hyphen" width="600" llx="143" lly="203" urx="567" ury="313"/> + <char name="i" width="600" llx="77" lly="0" urx="546" ury="658"/> + <char name="iacute" width="600" llx="77" lly="0" urx="609" ury="661"/> + <char name="icircumflex" width="600" llx="77" lly="0" urx="577" ury="657"/> + <char name="idieresis" width="600" llx="77" lly="0" urx="561" ury="618"/> + <char name="igrave" width="600" llx="77" lly="0" urx="546" ury="661"/> + <char name="j" width="600" llx="36" lly="-146" urx="580" ury="658"/> + <char name="k" width="600" llx="33" lly="0" urx="643" ury="626"/> + <char name="l" width="600" llx="77" lly="0" urx="546" ury="626"/> + <char name="less" width="600" llx="120" lly="15" urx="613" ury="501"/> + <char name="logicalnot" width="600" llx="135" lly="103" urx="617" ury="413"/> + <char name="lslash" width="600" llx="77" lly="0" urx="587" ury="626"/> + <char name="m" width="600" llx="-22" lly="0" urx="649" ury="454"/> + <char name="macron" width="600" llx="195" lly="505" urx="637" ury="585"/> + <char name="minus" width="600" llx="114" lly="203" urx="596" ury="313"/> + <char name="mu" width="600" llx="49" lly="-142" urx="592" ury="439"/> + <char name="multiply" width="600" llx="104" lly="39" urx="606" ury="478"/> + <char name="n" width="600" llx="18" lly="0" urx="615" ury="454"/> + <char name="nine" width="600" llx="75" lly="-15" urx="592" ury="616"/> + <char name="ntilde" width="600" llx="18" lly="0" urx="643" ury="636"/> + <char name="numbersign" width="600" llx="88" lly="-45" urx="641" ury="651"/> + <char name="o" width="600" llx="71" lly="-15" urx="622" ury="454"/> + <char name="oacute" width="600" llx="71" lly="-15" urx="649" ury="661"/> + <char name="ocircumflex" width="600" llx="71" lly="-15" urx="622" ury="657"/> + <char name="odieresis" width="600" llx="71" lly="-15" urx="622" ury="638"/> + <char name="oe" width="600" llx="18" lly="-15" urx="662" ury="454"/> + <char name="ogonek" width="600" llx="143" lly="-199" urx="367" ury="0"/> + <char name="ograve" width="600" llx="71" lly="-15" urx="622" ury="661"/> + <char name="one" width="600" llx="93" lly="0" urx="562" ury="616"/> + <char name="onehalf" width="600" llx="22" lly="-60" urx="716" ury="661"/> + <char name="onequarter" width="600" llx="13" lly="-60" urx="707" ury="661"/> + <char name="onesuperior" width="600" llx="212" lly="230" urx="514" ury="616"/> + <char name="ordfeminine" width="600" llx="188" lly="196" urx="526" ury="580"/> + <char name="ordmasculine" width="600" llx="188" lly="196" urx="543" ury="580"/> + <char name="oslash" width="600" llx="54" lly="-24" urx="638" ury="463"/> + <char name="otilde" width="600" llx="71" lly="-15" urx="643" ury="636"/> + <char name="p" width="600" llx="-32" lly="-142" urx="622" ury="454"/> + <char name="paragraph" width="600" llx="61" lly="-70" urx="700" ury="580"/> + <char name="parenleft" width="600" llx="265" lly="-102" urx="592" ury="616"/> + <char name="parenright" width="600" llx="117" lly="-102" urx="444" ury="616"/> + <char name="percent" width="600" llx="101" lly="-15" urx="625" ury="616"/> + <char name="period" width="600" llx="206" lly="-15" urx="427" ury="171"/> + <char name="periodcentered" width="600" llx="248" lly="165" urx="461" ury="351"/> + <char name="perthousand" width="600" llx="-45" lly="-15" urx="743" ury="616"/> + <char name="plus" width="600" llx="114" lly="39" urx="596" ury="478"/> + <char name="plusminus" width="600" llx="76" lly="24" urx="614" ury="515"/> + <char name="q" width="600" llx="60" lly="-142" urx="685" ury="454"/> + <char name="question" width="600" llx="183" lly="-14" urx="592" ury="580"/> + <char name="questiondown" width="600" llx="100" lly="-146" urx="509" ury="449"/> + <char name="quotedbl" width="600" llx="211" lly="277" urx="585" ury="562"/> + <char name="quotedblbase" width="600" llx="34" lly="-142" urx="560" ury="143"/> + <char name="quotedblleft" width="600" llx="190" lly="277" urx="594" ury="562"/> + <char name="quotedblright" width="600" llx="119" lly="277" urx="645" ury="562"/> + <char name="quoteleft" width="600" llx="297" lly="277" urx="487" ury="562"/> + <char name="quoteright" width="600" llx="229" lly="277" urx="543" ury="562"/> + <char name="quotesinglbase" width="600" llx="144" lly="-142" urx="458" ury="143"/> + <char name="quotesingle" width="600" llx="303" lly="277" urx="493" ury="562"/> + <char name="r" width="600" llx="47" lly="0" urx="655" ury="454"/> + <char name="registered" width="600" llx="53" lly="-18" urx="667" ury="580"/> + <char name="ring" width="600" llx="319" lly="481" urx="528" ury="678"/> + <char name="s" width="600" llx="66" lly="-17" urx="608" ury="459"/> + <char name="scaron" width="600" llx="66" lly="-17" urx="633" ury="667"/> + <char name="scedilla" width="600" llx="66" lly="-206" urx="608" ury="459"/> + <char name="section" width="600" llx="74" lly="-70" urx="620" ury="580"/> + <char name="semicolon" width="600" llx="99" lly="-111" urx="481" ury="425"/> + <char name="seven" width="600" llx="147" lly="0" urx="622" ury="601"/> + <char name="six" width="600" llx="135" lly="-15" urx="652" ury="616"/> + <char name="slash" width="600" llx="90" lly="-77" urx="626" ury="626"/> + <char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="600"/> - <char name="square" width="600"/> - <char name="sterling" width="600"/> - <char name="stop" width="600"/> - <char name="t" width="600"/> - <char name="tab" width="600"/> - <char name="thorn" width="600"/> - <char name="three" width="600"/> - <char name="threequarters" width="600"/> - <char name="threesuperior" width="600"/> - <char name="tilde" width="600"/> - <char name="trademark" width="600"/> - <char name="two" width="600"/> - <char name="twosuperior" width="600"/> - <char name="u" width="600"/> - <char name="uacute" width="600"/> - <char name="ucircumflex" width="600"/> - <char name="udieresis" width="600"/> - <char name="ugrave" width="600"/> - <char name="underscore" width="600"/> - <char name="up" width="600"/> - <char name="v" width="600"/> - <char name="w" width="600"/> - <char name="x" width="600"/> - <char name="y" width="600"/> - <char name="yacute" width="600"/> - <char name="ydieresis" width="600"/> - <char name="yen" width="600"/> - <char name="z" width="600"/> - <char name="zcaron" width="600"/> - <char name="zero" width="600"/> - </widths> + <char name="sterling" width="600" llx="106" lly="-28" urx="650" ury="611"/> + <char name="t" width="600" llx="118" lly="-15" urx="567" ury="562"/> + <char name="thorn" width="600" llx="-32" lly="-142" urx="622" ury="626"/> + <char name="three" width="600" llx="71" lly="-15" urx="571" ury="616"/> + <char name="threequarters" width="600" llx="8" lly="-60" urx="699" ury="661"/> + <char name="threesuperior" width="600" llx="193" lly="222" urx="526" ury="616"/> + <char name="tilde" width="600" llx="199" lly="493" urx="643" ury="636"/> + <char name="trademark" width="600" llx="86" lly="230" urx="869" ury="562"/> + <char name="two" width="600" llx="61" lly="0" urx="594" ury="616"/> + <char name="twosuperior" width="600" llx="191" lly="230" urx="542" ury="616"/> + <char name="u" width="600" llx="70" lly="-15" urx="592" ury="439"/> + <char name="uacute" width="600" llx="70" lly="-15" urx="599" ury="661"/> + <char name="ucircumflex" width="600" llx="70" lly="-15" urx="597" ury="657"/> + <char name="udieresis" width="600" llx="70" lly="-15" urx="595" ury="638"/> + <char name="ugrave" width="600" llx="70" lly="-15" urx="592" ury="661"/> + <char name="underscore" width="600" llx="-27" lly="-125" urx="585" ury="-75"/> + <char name="v" width="600" llx="70" lly="0" urx="695" ury="439"/> + <char name="w" width="600" llx="53" lly="0" urx="712" ury="439"/> + <char name="x" width="600" llx="6" lly="0" urx="671" ury="439"/> + <char name="y" width="600" llx="-21" lly="-142" urx="695" ury="439"/> + <char name="yacute" width="600" llx="-21" lly="-142" urx="695" ury="661"/> + <char name="ydieresis" width="600" llx="-21" lly="-142" urx="695" ury="638"/> + <char name="yen" width="600" llx="98" lly="0" urx="710" ury="562"/> + <char name="z" width="600" llx="81" lly="0" urx="614" ury="439"/> + <char name="zcaron" width="600" llx="81" lly="0" urx="643" ury="667"/> + <char name="zero" width="600" llx="135" lly="-15" urx="593" ury="616"/> + </char-metrics> </font-metrics> diff --git a/src/codegen/fonts/CourierOblique.xml b/src/codegen/fonts/CourierOblique.xml index 2dc300645..e08fa9b9b 100644 --- a/src/codegen/fonts/CourierOblique.xml +++ b/src/codegen/fonts/CourierOblique.xml @@ -22,275 +22,246 @@ <family-name>Courier</family-name> <class-name>CourierOblique</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>562</cap-height> <x-height>426</x-height> <ascender>629</ascender> <descender>-157</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="600"/> - <char name="AE" width="600"/> - <char name="Aacute" width="600"/> - <char name="Acircumflex" width="600"/> - <char name="Adieresis" width="600"/> - <char name="Agrave" width="600"/> - <char name="Aring" width="600"/> - <char name="Atilde" width="600"/> - <char name="B" width="600"/> - <char name="C" width="600"/> - <char name="Ccedilla" width="600"/> - <char name="D" width="600"/> - <char name="E" width="600"/> - <char name="Eacute" width="600"/> - <char name="Ecircumflex" width="600"/> - <char name="Edieresis" width="600"/> - <char name="Egrave" width="600"/> - <char name="Eth" width="600"/> - <char name="Euro" width="600"/> - <char name="F" width="600"/> - <char name="G" width="600"/> - <char name="Gcaron" width="600"/> - <char name="H" width="600"/> - <char name="I" width="600"/> - <char name="IJ" width="600"/> - <char name="Iacute" width="600"/> - <char name="Icircumflex" width="600"/> - <char name="Idieresis" width="600"/> - <char name="Idot" width="600"/> - <char name="Igrave" width="600"/> - <char name="J" width="600"/> - <char name="K" width="600"/> - <char name="L" width="600"/> - <char name="LL" width="600"/> - <char name="Lslash" width="600"/> - <char name="M" width="600"/> - <char name="N" width="600"/> - <char name="Ntilde" width="600"/> - <char name="O" width="600"/> - <char name="OE" width="600"/> - <char name="Oacute" width="600"/> - <char name="Ocircumflex" width="600"/> - <char name="Odieresis" width="600"/> - <char name="Ograve" width="600"/> - <char name="Oslash" width="600"/> - <char name="Otilde" width="600"/> - <char name="P" width="600"/> - <char name="Q" width="600"/> - <char name="R" width="600"/> - <char name="S" width="600"/> - <char name="Scaron" width="600"/> - <char name="Scedilla" width="600"/> - <char name="T" width="600"/> - <char name="Thorn" width="600"/> - <char name="U" width="600"/> - <char name="Uacute" width="600"/> - <char name="Ucircumflex" width="600"/> - <char name="Udieresis" width="600"/> - <char name="Ugrave" width="600"/> - <char name="V" width="600"/> - <char name="W" width="600"/> - <char name="X" width="600"/> - <char name="Y" width="600"/> - <char name="Yacute" width="600"/> - <char name="Ydieresis" width="600"/> - <char name="Z" width="600"/> - <char name="Zcaron" width="600"/> - <char name="a" width="600"/> - <char name="aacute" width="600"/> - <char name="acircumflex" width="600"/> - <char name="acute" width="600"/> - <char name="adieresis" width="600"/> - <char name="ae" width="600"/> - <char name="agrave" width="600"/> - <char name="ampersand" width="600"/> - <char name="aring" width="600"/> - <char name="arrowboth" width="600"/> - <char name="arrowdown" width="600"/> - <char name="arrowleft" width="600"/> - <char name="arrowright" width="600"/> - <char name="arrowup" width="600"/> - <char name="asciicircum" width="600"/> - <char name="asciitilde" width="600"/> - <char name="asterisk" width="600"/> - <char name="at" width="600"/> - <char name="atilde" width="600"/> - <char name="b" width="600"/> - <char name="backslash" width="600"/> - <char name="bar" width="600"/> - <char name="braceleft" width="600"/> - <char name="braceright" width="600"/> - <char name="bracketleft" width="600"/> - <char name="bracketright" width="600"/> - <char name="breve" width="600"/> - <char name="brokenbar" width="600"/> - <char name="bullet" width="600"/> - <char name="c" width="600"/> - <char name="caron" width="600"/> - <char name="ccedilla" width="600"/> - <char name="cedilla" width="600"/> - <char name="cent" width="600"/> - <char name="center" width="600"/> - <char name="circumflex" width="600"/> - <char name="colon" width="600"/> - <char name="comma" width="600"/> - <char name="copyright" width="600"/> - <char name="currency" width="600"/> - <char name="d" width="600"/> - <char name="dagger" width="600"/> - <char name="daggerdbl" width="600"/> - <char name="dectab" width="600"/> - <char name="degree" width="600"/> - <char name="dieresis" width="600"/> - <char name="divide" width="600"/> - <char name="dollar" width="600"/> - <char name="dotaccent" width="600"/> - <char name="dotlessi" width="600"/> - <char name="down" width="600"/> - <char name="e" width="600"/> - <char name="eacute" width="600"/> - <char name="ecircumflex" width="600"/> - <char name="edieresis" width="600"/> - <char name="egrave" width="600"/> - <char name="eight" width="600"/> - <char name="ellipsis" width="600"/> - <char name="emdash" width="600"/> - <char name="endash" width="600"/> - <char name="equal" width="600"/> - <char name="eth" width="600"/> - <char name="exclam" width="600"/> - <char name="exclamdown" width="600"/> - <char name="f" width="600"/> - <char name="fi" width="600"/> - <char name="five" width="600"/> - <char name="fl" width="600"/> - <char name="florin" width="600"/> - <char name="format" width="600"/> - <char name="four" width="600"/> - <char name="fraction" width="600"/> - <char name="g" width="600"/> - <char name="gcaron" width="600"/> - <char name="germandbls" width="600"/> - <char name="grave" width="600"/> - <char name="graybox" width="600"/> - <char name="greater" width="600"/> - <char name="guillemotleft" width="600"/> - <char name="guillemotright" width="600"/> - <char name="guilsinglleft" width="600"/> - <char name="guilsinglright" width="600"/> - <char name="h" width="600"/> - <char name="hungarumlaut" width="600"/> - <char name="hyphen" width="600"/> - <char name="i" width="600"/> - <char name="iacute" width="600"/> - <char name="icircumflex" width="600"/> - <char name="idieresis" width="600"/> - <char name="igrave" width="600"/> - <char name="ij" width="600"/> - <char name="indent" width="600"/> - <char name="j" width="600"/> - <char name="k" width="600"/> - <char name="l" width="600"/> - <char name="largebullet" width="600"/> - <char name="left" width="600"/> - <char name="less" width="600"/> - <char name="lira" width="600"/> - <char name="ll" width="600"/> - <char name="logicalnot" width="600"/> - <char name="lslash" width="600"/> - <char name="m" width="600"/> - <char name="macron" width="600"/> - <char name="merge" width="600"/> - <char name="minus" width="600"/> - <char name="mu" width="600"/> - <char name="multiply" width="600"/> - <char name="n" width="600"/> - <char name="nine" width="600"/> - <char name="notegraphic" width="600"/> - <char name="ntilde" width="600"/> - <char name="numbersign" width="600"/> - <char name="o" width="600"/> - <char name="oacute" width="600"/> - <char name="ocircumflex" width="600"/> - <char name="odieresis" width="600"/> - <char name="oe" width="600"/> - <char name="ogonek" width="600"/> - <char name="ograve" width="600"/> - <char name="one" width="600"/> - <char name="onehalf" width="600"/> - <char name="onequarter" width="600"/> - <char name="onesuperior" width="600"/> - <char name="ordfeminine" width="600"/> - <char name="ordmasculine" width="600"/> - <char name="oslash" width="600"/> - <char name="otilde" width="600"/> - <char name="overscore" width="600"/> - <char name="p" width="600"/> - <char name="paragraph" width="600"/> - <char name="parenleft" width="600"/> - <char name="parenright" width="600"/> - <char name="percent" width="600"/> - <char name="period" width="600"/> - <char name="periodcentered" width="600"/> - <char name="perthousand" width="600"/> - <char name="plus" width="600"/> - <char name="plusminus" width="600"/> - <char name="prescription" width="600"/> - <char name="q" width="600"/> - <char name="question" width="600"/> - <char name="questiondown" width="600"/> - <char name="quotedbl" width="600"/> - <char name="quotedblbase" width="600"/> - <char name="quotedblleft" width="600"/> - <char name="quotedblright" width="600"/> - <char name="quoteleft" width="600"/> - <char name="quoteright" width="600"/> - <char name="quotesinglbase" width="600"/> - <char name="quotesingle" width="600"/> - <char name="r" width="600"/> - <char name="registered" width="600"/> - <char name="return" width="600"/> - <char name="ring" width="600"/> - <char name="s" width="600"/> - <char name="scaron" width="600"/> - <char name="scedilla" width="600"/> - <char name="section" width="600"/> - <char name="semicolon" width="600"/> - <char name="seven" width="600"/> - <char name="six" width="600"/> - <char name="slash" width="600"/> - <char name="space" width="600"/> + <char-metrics> + <char name="A" width="600" llx="3" lly="0" urx="607" ury="562"/> + <char name="AE" width="600" llx="3" lly="0" urx="655" ury="562"/> + <char name="Aacute" width="600" llx="3" lly="0" urx="660" ury="805"/> + <char name="Acircumflex" width="600" llx="3" lly="0" urx="607" ury="787"/> + <char name="Adieresis" width="600" llx="3" lly="0" urx="607" ury="753"/> + <char name="Agrave" width="600" llx="3" lly="0" urx="607" ury="805"/> + <char name="Aring" width="600" llx="3" lly="0" urx="607" ury="750"/> + <char name="Atilde" width="600" llx="3" lly="0" urx="655" ury="729"/> + <char name="B" width="600" llx="43" lly="0" urx="616" ury="562"/> + <char name="C" width="600" llx="93" lly="-18" urx="655" ury="580"/> + <char name="Ccedilla" width="600" llx="93" lly="-151" urx="658" ury="580"/> + <char name="D" width="600" llx="43" lly="0" urx="645" ury="562"/> + <char name="E" width="600" llx="53" lly="0" urx="660" ury="562"/> + <char name="Eacute" width="600" llx="53" lly="0" urx="670" ury="805"/> + <char name="Ecircumflex" width="600" llx="53" lly="0" urx="660" ury="787"/> + <char name="Edieresis" width="600" llx="53" lly="0" urx="660" ury="753"/> + <char name="Egrave" width="600" llx="53" lly="0" urx="660" ury="805"/> + <char name="Eth" width="600" llx="43" lly="0" urx="645" ury="562"/> + <char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="600" llx="53" lly="0" urx="660" ury="562"/> + <char name="G" width="600" llx="83" lly="-18" urx="645" ury="580"/> + <char name="H" width="600" llx="32" lly="0" urx="687" ury="562"/> + <char name="I" width="600" llx="96" lly="0" urx="623" ury="562"/> + <char name="Iacute" width="600" llx="96" lly="0" urx="640" ury="805"/> + <char name="Icircumflex" width="600" llx="96" lly="0" urx="623" ury="787"/> + <char name="Idieresis" width="600" llx="96" lly="0" urx="623" ury="753"/> + <char name="Igrave" width="600" llx="96" lly="0" urx="623" ury="805"/> + <char name="J" width="600" llx="52" lly="-18" urx="685" ury="562"/> + <char name="K" width="600" llx="38" lly="0" urx="671" ury="562"/> + <char name="L" width="600" llx="47" lly="0" urx="607" ury="562"/> + <char name="Lslash" width="600" llx="47" lly="0" urx="607" ury="562"/> + <char name="M" width="600" llx="4" lly="0" urx="715" ury="562"/> + <char name="N" width="600" llx="7" lly="-13" urx="712" ury="562"/> + <char name="Ntilde" width="600" llx="7" lly="-13" urx="712" ury="729"/> + <char name="O" width="600" llx="94" lly="-18" urx="625" ury="580"/> + <char name="OE" width="600" llx="59" lly="0" urx="672" ury="562"/> + <char name="Oacute" width="600" llx="94" lly="-18" urx="640" ury="805"/> + <char name="Ocircumflex" width="600" llx="94" lly="-18" urx="625" ury="787"/> + <char name="Odieresis" width="600" llx="94" lly="-18" urx="625" ury="753"/> + <char name="Ograve" width="600" llx="94" lly="-18" urx="625" ury="805"/> + <char name="Oslash" width="600" llx="94" lly="-80" urx="625" ury="629"/> + <char name="Otilde" width="600" llx="94" lly="-18" urx="655" ury="729"/> + <char name="P" width="600" llx="79" lly="0" urx="644" ury="562"/> + <char name="Q" width="600" llx="95" lly="-138" urx="625" ury="580"/> + <char name="R" width="600" llx="38" lly="0" urx="598" ury="562"/> + <char name="S" width="600" llx="76" lly="-20" urx="650" ury="580"/> + <char name="Scaron" width="600" llx="76" lly="-20" urx="672" ury="802"/> + <char name="Scedilla" width="600" llx="76" lly="-151" urx="650" ury="580"/> + <char name="T" width="600" llx="108" lly="0" urx="665" ury="562"/> + <char name="Thorn" width="600" llx="79" lly="0" urx="606" ury="562"/> + <char name="U" width="600" llx="125" lly="-18" urx="702" ury="562"/> + <char name="Uacute" width="600" llx="125" lly="-18" urx="702" ury="805"/> + <char name="Ucircumflex" width="600" llx="125" lly="-18" urx="702" ury="787"/> + <char name="Udieresis" width="600" llx="125" lly="-18" urx="702" ury="753"/> + <char name="Ugrave" width="600" llx="125" lly="-18" urx="702" ury="805"/> + <char name="V" width="600" llx="105" lly="-13" urx="723" ury="562"/> + <char name="W" width="600" llx="106" lly="-13" urx="722" ury="562"/> + <char name="X" width="600" llx="23" lly="0" urx="675" ury="562"/> + <char name="Y" width="600" llx="133" lly="0" urx="695" ury="562"/> + <char name="Yacute" width="600" llx="133" lly="0" urx="695" ury="805"/> + <char name="Ydieresis" width="600" llx="133" lly="0" urx="695" ury="753"/> + <char name="Z" width="600" llx="86" lly="0" urx="610" ury="562"/> + <char name="Zcaron" width="600" llx="86" lly="0" urx="642" ury="802"/> + <char name="a" width="600" llx="76" lly="-15" urx="569" ury="441"/> + <char name="aacute" width="600" llx="76" lly="-15" urx="612" ury="672"/> + <char name="acircumflex" width="600" llx="76" lly="-15" urx="581" ury="654"/> + <char name="acute" width="600" llx="348" lly="497" urx="612" ury="672"/> + <char name="adieresis" width="600" llx="76" lly="-15" urx="575" ury="620"/> + <char name="ae" width="600" llx="41" lly="-15" urx="626" ury="441"/> + <char name="agrave" width="600" llx="76" lly="-15" urx="569" ury="672"/> + <char name="ampersand" width="600" llx="87" lly="-15" urx="580" ury="543"/> + <char name="aring" width="600" llx="76" lly="-15" urx="569" ury="627"/> + <char name="asciicircum" width="600" llx="175" lly="354" urx="587" ury="622"/> + <char name="asciitilde" width="600" llx="116" lly="197" urx="600" ury="320"/> + <char name="asterisk" width="600" llx="212" lly="257" urx="580" ury="607"/> + <char name="at" width="600" llx="127" lly="-15" urx="582" ury="622"/> + <char name="atilde" width="600" llx="76" lly="-15" urx="629" ury="606"/> + <char name="b" width="600" llx="29" lly="-15" urx="625" ury="629"/> + <char name="backslash" width="600" llx="249" lly="-80" urx="468" ury="629"/> + <char name="bar" width="600" llx="222" lly="-250" urx="485" ury="750"/> + <char name="braceleft" width="600" llx="233" lly="-108" urx="569" ury="622"/> + <char name="braceright" width="600" llx="140" lly="-108" urx="477" ury="622"/> + <char name="bracketleft" width="600" llx="246" lly="-108" urx="574" ury="622"/> + <char name="bracketright" width="600" llx="135" lly="-108" urx="463" ury="622"/> + <char name="breve" width="600" llx="279" lly="501" urx="576" ury="609"/> + <char name="brokenbar" width="600" llx="238" lly="-175" urx="469" ury="675"/> + <char name="bullet" width="600" llx="224" lly="130" urx="485" ury="383"/> + <char name="c" width="600" llx="106" lly="-15" urx="608" ury="441"/> + <char name="caron" width="600" llx="262" lly="492" urx="614" ury="669"/> + <char name="ccedilla" width="600" llx="106" lly="-151" urx="614" ury="441"/> + <char name="cedilla" width="600" llx="197" lly="-151" urx="344" ury="10"/> + <char name="cent" width="600" llx="151" lly="-49" urx="588" ury="614"/> + <char name="circumflex" width="600" llx="229" lly="477" urx="581" ury="654"/> + <char name="colon" width="600" llx="238" lly="-15" urx="441" ury="385"/> + <char name="comma" width="600" llx="157" lly="-112" urx="370" ury="122"/> + <char name="copyright" width="600" llx="53" lly="-18" urx="667" ury="580"/> + <char name="currency" width="600" llx="94" lly="58" urx="628" ury="506"/> + <char name="d" width="600" llx="85" lly="-15" urx="640" ury="629"/> + <char name="dagger" width="600" llx="217" lly="-78" urx="546" ury="580"/> + <char name="daggerdbl" width="600" llx="163" lly="-78" urx="546" ury="580"/> + <char name="degree" width="600" llx="214" lly="269" urx="576" ury="622"/> + <char name="dieresis" width="600" llx="272" lly="537" urx="579" ury="640"/> + <char name="divide" width="600" llx="136" lly="48" urx="573" ury="467"/> + <char name="dollar" width="600" llx="108" lly="-126" urx="596" ury="662"/> + <char name="dotaccent" width="600" llx="373" lly="537" urx="478" ury="640"/> + <char name="dotlessi" width="600" llx="95" lly="0" urx="515" ury="426"/> + <char name="e" width="600" llx="106" lly="-15" urx="598" ury="441"/> + <char name="eacute" width="600" llx="106" lly="-15" urx="612" ury="672"/> + <char name="ecircumflex" width="600" llx="106" lly="-15" urx="598" ury="654"/> + <char name="edieresis" width="600" llx="106" lly="-15" urx="598" ury="620"/> + <char name="egrave" width="600" llx="106" lly="-15" urx="598" ury="672"/> + <char name="eight" width="600" llx="132" lly="-15" urx="588" ury="622"/> + <char name="ellipsis" width="600" llx="46" lly="-15" urx="575" ury="111"/> + <char name="emdash" width="600" llx="49" lly="231" urx="661" ury="285"/> + <char name="endash" width="600" llx="124" lly="231" urx="586" ury="285"/> + <char name="equal" width="600" llx="109" lly="138" urx="600" ury="376"/> + <char name="eth" width="600" llx="102" lly="-15" urx="639" ury="629"/> + <char name="exclam" width="600" llx="243" lly="-15" urx="464" ury="572"/> + <char name="exclamdown" width="600" llx="225" lly="-157" urx="445" ury="430"/> + <char name="f" width="600" llx="114" lly="0" urx="662" ury="629"/> + <char name="fi" width="600" llx="3" lly="0" urx="619" ury="629"/> + <char name="five" width="600" llx="99" lly="-15" urx="589" ury="607"/> + <char name="fl" width="600" llx="3" lly="0" urx="619" ury="629"/> + <char name="florin" width="600" llx="-26" lly="-143" urx="671" ury="622"/> + <char name="four" width="600" llx="108" lly="0" urx="541" ury="622"/> + <char name="fraction" width="600" llx="84" lly="-57" urx="646" ury="665"/> + <char name="g" width="600" llx="61" lly="-157" urx="657" ury="441"/> + <char name="germandbls" width="600" llx="48" lly="-15" urx="617" ury="629"/> + <char name="grave" width="600" llx="294" lly="497" urx="484" ury="672"/> + <char name="greater" width="600" llx="85" lly="42" urx="599" ury="472"/> + <char name="guillemotleft" width="600" llx="92" lly="70" urx="652" ury="446"/> + <char name="guillemotright" width="600" llx="58" lly="70" urx="618" ury="446"/> + <char name="guilsinglleft" width="600" llx="204" lly="70" urx="540" ury="446"/> + <char name="guilsinglright" width="600" llx="170" lly="70" urx="506" ury="446"/> + <char name="h" width="600" llx="33" lly="0" urx="592" ury="629"/> + <char name="hungarumlaut" width="600" llx="239" lly="497" urx="683" ury="672"/> + <char name="hyphen" width="600" llx="152" lly="231" urx="558" ury="285"/> + <char name="i" width="600" llx="95" lly="0" urx="515" ury="657"/> + <char name="iacute" width="600" llx="95" lly="0" urx="612" ury="672"/> + <char name="icircumflex" width="600" llx="95" lly="0" urx="551" ury="654"/> + <char name="idieresis" width="600" llx="95" lly="0" urx="545" ury="620"/> + <char name="igrave" width="600" llx="95" lly="0" urx="515" ury="672"/> + <char name="j" width="600" llx="52" lly="-157" urx="550" ury="657"/> + <char name="k" width="600" llx="58" lly="0" urx="633" ury="629"/> + <char name="l" width="600" llx="95" lly="0" urx="515" ury="629"/> + <char name="less" width="600" llx="96" lly="42" urx="610" ury="472"/> + <char name="logicalnot" width="600" llx="155" lly="108" urx="591" ury="369"/> + <char name="lslash" width="600" llx="95" lly="0" urx="587" ury="629"/> + <char name="m" width="600" llx="-5" lly="0" urx="615" ury="441"/> + <char name="macron" width="600" llx="232" lly="525" urx="600" ury="565"/> + <char name="minus" width="600" llx="129" lly="232" urx="580" ury="283"/> + <char name="mu" width="600" llx="72" lly="-157" urx="572" ury="426"/> + <char name="multiply" width="600" llx="103" lly="43" urx="607" ury="470"/> + <char name="n" width="600" llx="26" lly="0" urx="585" ury="441"/> + <char name="nine" width="600" llx="93" lly="-15" urx="574" ury="622"/> + <char name="ntilde" width="600" llx="26" lly="0" urx="629" ury="606"/> + <char name="numbersign" width="600" llx="133" lly="-32" urx="596" ury="639"/> + <char name="o" width="600" llx="102" lly="-15" urx="588" ury="441"/> + <char name="oacute" width="600" llx="102" lly="-15" urx="612" ury="672"/> + <char name="ocircumflex" width="600" llx="102" lly="-15" urx="588" ury="654"/> + <char name="odieresis" width="600" llx="102" lly="-15" urx="588" ury="620"/> + <char name="oe" width="600" llx="54" lly="-15" urx="615" ury="441"/> + <char name="ogonek" width="600" llx="189" lly="-172" urx="377" ury="4"/> + <char name="ograve" width="600" llx="102" lly="-15" urx="588" ury="672"/> + <char name="one" width="600" llx="98" lly="0" urx="515" ury="622"/> + <char name="onehalf" width="600" llx="65" lly="-57" urx="669" ury="665"/> + <char name="onequarter" width="600" llx="65" lly="-57" urx="674" ury="665"/> + <char name="onesuperior" width="600" llx="231" lly="249" urx="491" ury="622"/> + <char name="ordfeminine" width="600" llx="209" lly="249" urx="512" ury="580"/> + <char name="ordmasculine" width="600" llx="210" lly="249" urx="535" ury="580"/> + <char name="oslash" width="600" llx="102" lly="-80" urx="588" ury="506"/> + <char name="otilde" width="600" llx="102" lly="-15" urx="629" ury="606"/> + <char name="p" width="600" llx="-24" lly="-157" urx="605" ury="441"/> + <char name="paragraph" width="600" llx="100" lly="-78" urx="630" ury="562"/> + <char name="parenleft" width="600" llx="313" lly="-108" urx="572" ury="622"/> + <char name="parenright" width="600" llx="137" lly="-108" urx="396" ury="622"/> + <char name="percent" width="600" llx="134" lly="-15" urx="599" ury="622"/> + <char name="period" width="600" llx="238" lly="-15" urx="382" ury="109"/> + <char name="periodcentered" width="600" llx="275" lly="189" urx="434" ury="327"/> + <char name="perthousand" width="600" llx="59" lly="-15" urx="627" ury="622"/> + <char name="plus" width="600" llx="129" lly="44" urx="580" ury="470"/> + <char name="plusminus" width="600" llx="96" lly="44" urx="594" ury="558"/> + <char name="q" width="600" llx="85" lly="-157" urx="682" ury="441"/> + <char name="question" width="600" llx="222" lly="-15" urx="583" ury="572"/> + <char name="questiondown" width="600" llx="105" lly="-157" urx="466" ury="430"/> + <char name="quotedbl" width="600" llx="273" lly="328" urx="532" ury="562"/> + <char name="quotedblbase" width="600" llx="115" lly="-134" urx="478" ury="100"/> + <char name="quotedblleft" width="600" llx="262" lly="328" urx="541" ury="562"/> + <char name="quotedblright" width="600" llx="213" lly="328" urx="576" ury="562"/> + <char name="quoteleft" width="600" llx="343" lly="328" urx="457" ury="562"/> + <char name="quoteright" width="600" llx="283" lly="328" urx="495" ury="562"/> + <char name="quotesinglbase" width="600" llx="185" lly="-134" urx="397" ury="100"/> + <char name="quotesingle" width="600" llx="345" lly="328" urx="460" ury="562"/> + <char name="r" width="600" llx="60" lly="0" urx="636" ury="441"/> + <char name="registered" width="600" llx="53" lly="-18" urx="667" ury="580"/> + <char name="ring" width="600" llx="332" lly="463" urx="500" ury="627"/> + <char name="s" width="600" llx="78" lly="-15" urx="584" ury="441"/> + <char name="scaron" width="600" llx="78" lly="-15" urx="614" ury="669"/> + <char name="scedilla" width="600" llx="78" lly="-151" urx="584" ury="441"/> + <char name="section" width="600" llx="104" lly="-78" urx="590" ury="580"/> + <char name="semicolon" width="600" llx="157" lly="-112" urx="441" ury="385"/> + <char name="seven" width="600" llx="182" lly="0" urx="612" ury="607"/> + <char name="six" width="600" llx="155" lly="-15" urx="629" ury="622"/> + <char name="slash" width="600" llx="112" lly="-80" urx="604" ury="629"/> + <char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="600"/> - <char name="square" width="600"/> - <char name="sterling" width="600"/> - <char name="stop" width="600"/> - <char name="t" width="600"/> - <char name="tab" width="600"/> - <char name="thorn" width="600"/> - <char name="three" width="600"/> - <char name="threequarters" width="600"/> - <char name="threesuperior" width="600"/> - <char name="tilde" width="600"/> - <char name="trademark" width="600"/> - <char name="two" width="600"/> - <char name="twosuperior" width="600"/> - <char name="u" width="600"/> - <char name="uacute" width="600"/> - <char name="ucircumflex" width="600"/> - <char name="udieresis" width="600"/> - <char name="ugrave" width="600"/> - <char name="underscore" width="600"/> - <char name="up" width="600"/> - <char name="v" width="600"/> - <char name="w" width="600"/> - <char name="x" width="600"/> - <char name="y" width="600"/> - <char name="yacute" width="600"/> - <char name="ydieresis" width="600"/> - <char name="yen" width="600"/> - <char name="z" width="600"/> - <char name="zcaron" width="600"/> - <char name="zero" width="600"/> - </widths> -</font-metrics>
\ No newline at end of file + <char name="sterling" width="600" llx="124" lly="-21" urx="621" ury="611"/> + <char name="t" width="600" llx="167" lly="-15" urx="561" ury="561"/> + <char name="thorn" width="600" llx="-24" lly="-157" urx="605" ury="629"/> + <char name="three" width="600" llx="82" lly="-15" urx="538" ury="622"/> + <char name="threequarters" width="600" llx="73" lly="-56" urx="659" ury="666"/> + <char name="threesuperior" width="600" llx="213" lly="240" urx="501" ury="622"/> + <char name="tilde" width="600" llx="212" lly="489" urx="629" ury="606"/> + <char name="trademark" width="600" llx="75" lly="263" urx="742" ury="562"/> + <char name="two" width="600" llx="70" lly="0" urx="568" ury="622"/> + <char name="twosuperior" width="600" llx="230" lly="249" urx="535" ury="622"/> + <char name="u" width="600" llx="101" lly="-15" urx="572" ury="426"/> + <char name="uacute" width="600" llx="101" lly="-15" urx="602" ury="672"/> + <char name="ucircumflex" width="600" llx="101" lly="-15" urx="572" ury="654"/> + <char name="udieresis" width="600" llx="101" lly="-15" urx="575" ury="620"/> + <char name="ugrave" width="600" llx="101" lly="-15" urx="572" ury="672"/> + <char name="underscore" width="600" llx="-27" lly="-125" urx="584" ury="-75"/> + <char name="v" width="600" llx="90" lly="-10" urx="681" ury="426"/> + <char name="w" width="600" llx="76" lly="-10" urx="695" ury="426"/> + <char name="x" width="600" llx="20" lly="0" urx="655" ury="426"/> + <char name="y" width="600" llx="-4" lly="-157" urx="683" ury="426"/> + <char name="yacute" width="600" llx="-4" lly="-157" urx="683" ury="672"/> + <char name="ydieresis" width="600" llx="-4" lly="-157" urx="683" ury="620"/> + <char name="yen" width="600" llx="120" lly="0" urx="693" ury="562"/> + <char name="z" width="600" llx="99" lly="0" urx="593" ury="426"/> + <char name="zcaron" width="600" llx="99" lly="0" urx="624" ury="669"/> + <char name="zero" width="600" llx="154" lly="-15" urx="575" ury="622"/> + </char-metrics> +</font-metrics> diff --git a/src/codegen/fonts/Helvetica.xml b/src/codegen/fonts/Helvetica.xml index 38ae23055..b6e11a72b 100644 --- a/src/codegen/fonts/Helvetica.xml +++ b/src/codegen/fonts/Helvetica.xml @@ -22,245 +22,246 @@ <family-name>Helvetica</family-name> <class-name>Helvetica</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>718</cap-height> <x-height>523</x-height> <ascender>718</ascender> <descender>-207</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="667"/> - <char name="AE" width="1000"/> - <char name="Aacute" width="667"/> - <char name="Acircumflex" width="667"/> - <char name="Adieresis" width="667"/> - <char name="Agrave" width="667"/> - <char name="Aring" width="667"/> - <char name="Atilde" width="667"/> - <char name="B" width="667"/> - <char name="C" width="722"/> - <char name="Ccedilla" width="722"/> - <char name="D" width="722"/> - <char name="E" width="667"/> - <char name="Eacute" width="667"/> - <char name="Ecircumflex" width="667"/> - <char name="Edieresis" width="667"/> - <char name="Egrave" width="667"/> - <char name="Eth" width="722"/> - <char name="Euro" width="556"/> - <char name="F" width="611"/> - <char name="G" width="778"/> - <char name="H" width="722"/> - <char name="I" width="278"/> - <char name="Iacute" width="278"/> - <char name="Icircumflex" width="278"/> - <char name="Idieresis" width="278"/> - <char name="Igrave" width="278"/> - <char name="J" width="500"/> - <char name="K" width="667"/> - <char name="L" width="556"/> - <char name="Lslash" width="556"/> - <char name="M" width="833"/> - <char name="N" width="722"/> - <char name="Ntilde" width="722"/> - <char name="O" width="778"/> - <char name="OE" width="1000"/> - <char name="Oacute" width="778"/> - <char name="Ocircumflex" width="778"/> - <char name="Odieresis" width="778"/> - <char name="Ograve" width="778"/> - <char name="Oslash" width="778"/> - <char name="Otilde" width="778"/> - <char name="P" width="667"/> - <char name="Q" width="778"/> - <char name="R" width="722"/> - <char name="S" width="667"/> - <char name="Scaron" width="667"/> - <char name="T" width="611"/> - <char name="Thorn" width="667"/> - <char name="U" width="722"/> - <char name="Uacute" width="722"/> - <char name="Ucircumflex" width="722"/> - <char name="Udieresis" width="722"/> - <char name="Ugrave" width="722"/> - <char name="V" width="667"/> - <char name="W" width="944"/> - <char name="X" width="667"/> - <char name="Y" width="667"/> - <char name="Yacute" width="667"/> - <char name="Ydieresis" width="667"/> - <char name="Z" width="611"/> - <char name="Zcaron" width="611"/> - <char name="a" width="556"/> - <char name="aacute" width="556"/> - <char name="acircumflex" width="556"/> - <char name="acute" width="333"/> - <char name="adieresis" width="556"/> - <char name="ae" width="889"/> - <char name="agrave" width="556"/> - <char name="ampersand" width="667"/> - <char name="aring" width="556"/> - <char name="asciicircum" width="469"/> - <char name="asciitilde" width="584"/> - <char name="asterisk" width="389"/> - <char name="at" width="1015"/> - <char name="atilde" width="556"/> - <char name="b" width="556"/> - <char name="backslash" width="278"/> - <char name="bar" width="260"/> - <char name="braceleft" width="334"/> - <char name="braceright" width="334"/> - <char name="bracketleft" width="278"/> - <char name="bracketright" width="278"/> - <char name="breve" width="333"/> - <char name="brokenbar" width="260"/> - <char name="bullet" width="350"/> - <char name="c" width="500"/> - <char name="caron" width="333"/> - <char name="ccedilla" width="500"/> - <char name="cedilla" width="333"/> - <char name="cent" width="556"/> - <char name="circumflex" width="333"/> - <char name="colon" width="278"/> - <char name="comma" width="278"/> - <char name="copyright" width="737"/> - <char name="currency" width="556"/> - <char name="d" width="556"/> - <char name="dagger" width="556"/> - <char name="daggerdbl" width="556"/> - <char name="degree" width="400"/> - <char name="dieresis" width="333"/> - <char name="divide" width="584"/> - <char name="dollar" width="556"/> - <char name="dotaccent" width="333"/> - <char name="dotlessi" width="278"/> - <char name="e" width="556"/> - <char name="eacute" width="556"/> - <char name="ecircumflex" width="556"/> - <char name="edieresis" width="556"/> - <char name="egrave" width="556"/> - <char name="eight" width="556"/> - <char name="ellipsis" width="1000"/> - <char name="emdash" width="1000"/> - <char name="endash" width="556"/> - <char name="equal" width="584"/> - <char name="eth" width="556"/> - <char name="exclam" width="278"/> - <char name="exclamdown" width="333"/> - <char name="f" width="278"/> - <char name="fi" width="500"/> - <char name="five" width="556"/> - <char name="fl" width="500"/> - <char name="florin" width="556"/> - <char name="four" width="556"/> - <char name="fraction" width="167"/> - <char name="g" width="556"/> - <char name="germandbls" width="611"/> - <char name="grave" width="333"/> - <char name="greater" width="584"/> - <char name="guillemotleft" width="556"/> - <char name="guillemotright" width="556"/> - <char name="guilsinglleft" width="333"/> - <char name="guilsinglright" width="333"/> - <char name="h" width="556"/> - <char name="hungarumlaut" width="333"/> - <char name="hyphen" width="333"/> - <char name="i" width="222"/> - <char name="iacute" width="278"/> - <char name="icircumflex" width="278"/> - <char name="idieresis" width="278"/> - <char name="igrave" width="278"/> - <char name="j" width="222"/> - <char name="k" width="500"/> - <char name="l" width="222"/> - <char name="less" width="584"/> - <char name="logicalnot" width="584"/> - <char name="lslash" width="222"/> - <char name="m" width="833"/> - <char name="macron" width="333"/> - <char name="minus" width="324"/> - <char name="mu" width="556"/> - <char name="multiply" width="584"/> - <char name="n" width="556"/> - <char name="nine" width="556"/> - <char name="ntilde" width="556"/> - <char name="numbersign" width="556"/> - <char name="o" width="556"/> - <char name="oacute" width="556"/> - <char name="ocircumflex" width="556"/> - <char name="odieresis" width="556"/> - <char name="oe" width="944"/> - <char name="ogonek" width="333"/> - <char name="ograve" width="556"/> - <char name="one" width="556"/> - <char name="onehalf" width="834"/> - <char name="onequarter" width="834"/> - <char name="onesuperior" width="333"/> - <char name="ordfeminine" width="370"/> - <char name="ordmasculine" width="365"/> - <char name="oslash" width="611"/> - <char name="otilde" width="556"/> - <char name="p" width="556"/> - <char name="paragraph" width="537"/> - <char name="parenleft" width="333"/> - <char name="parenright" width="333"/> - <char name="percent" width="889"/> - <char name="period" width="278"/> - <char name="periodcentered" width="278"/> - <char name="perthousand" width="1000"/> - <char name="plus" width="584"/> - <char name="plusminus" width="584"/> - <char name="q" width="556"/> - <char name="question" width="556"/> - <char name="questiondown" width="611"/> - <char name="quotedbl" width="355"/> - <char name="quotedblbase" width="333"/> - <char name="quotedblleft" width="333"/> - <char name="quotedblright" width="333"/> - <char name="quoteleft" width="222"/> - <char name="quoteright" width="222"/> - <char name="quotesinglbase" width="222"/> - <char name="quotesingle" width="191"/> - <char name="r" width="333"/> - <char name="registered" width="737"/> - <char name="ring" width="333"/> - <char name="s" width="500"/> - <char name="scaron" width="500"/> - <char name="section" width="556"/> - <char name="semicolon" width="278"/> - <char name="seven" width="556"/> - <char name="six" width="556"/> - <char name="slash" width="278"/> - <char name="space" width="278"/> + <char-metrics> + <char name="A" width="667" llx="14" lly="0" urx="654" ury="718"/> + <char name="AE" width="1000" llx="8" lly="0" urx="951" ury="718"/> + <char name="Aacute" width="667" llx="14" lly="0" urx="654" ury="929"/> + <char name="Acircumflex" width="667" llx="14" lly="0" urx="654" ury="929"/> + <char name="Adieresis" width="667" llx="14" lly="0" urx="654" ury="901"/> + <char name="Agrave" width="667" llx="14" lly="0" urx="654" ury="929"/> + <char name="Aring" width="667" llx="14" lly="0" urx="654" ury="931"/> + <char name="Atilde" width="667" llx="14" lly="0" urx="654" ury="917"/> + <char name="B" width="667" llx="74" lly="0" urx="627" ury="718"/> + <char name="C" width="722" llx="44" lly="-19" urx="681" ury="737"/> + <char name="Ccedilla" width="722" llx="44" lly="-225" urx="681" ury="737"/> + <char name="D" width="722" llx="81" lly="0" urx="674" ury="718"/> + <char name="E" width="667" llx="86" lly="0" urx="616" ury="718"/> + <char name="Eacute" width="667" llx="86" lly="0" urx="616" ury="929"/> + <char name="Ecircumflex" width="667" llx="86" lly="0" urx="616" ury="929"/> + <char name="Edieresis" width="667" llx="86" lly="0" urx="616" ury="901"/> + <char name="Egrave" width="667" llx="86" lly="0" urx="616" ury="929"/> + <char name="Eth" width="722" llx="0" lly="0" urx="674" ury="718"/> + <char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="611" llx="86" lly="0" urx="583" ury="718"/> + <char name="G" width="778" llx="48" lly="-19" urx="704" ury="737"/> + <char name="H" width="722" llx="77" lly="0" urx="646" ury="718"/> + <char name="I" width="278" llx="91" lly="0" urx="188" ury="718"/> + <char name="Iacute" width="278" llx="91" lly="0" urx="292" ury="929"/> + <char name="Icircumflex" width="278" llx="-6" lly="0" urx="285" ury="929"/> + <char name="Idieresis" width="278" llx="13" lly="0" urx="266" ury="901"/> + <char name="Igrave" width="278" llx="-13" lly="0" urx="188" ury="929"/> + <char name="J" width="500" llx="17" lly="-19" urx="428" ury="718"/> + <char name="K" width="667" llx="76" lly="0" urx="663" ury="718"/> + <char name="L" width="556" llx="76" lly="0" urx="537" ury="718"/> + <char name="Lslash" width="556" llx="-20" lly="0" urx="537" ury="718"/> + <char name="M" width="833" llx="73" lly="0" urx="761" ury="718"/> + <char name="N" width="722" llx="76" lly="0" urx="646" ury="718"/> + <char name="Ntilde" width="722" llx="76" lly="0" urx="646" ury="917"/> + <char name="O" width="778" llx="39" lly="-19" urx="739" ury="737"/> + <char name="OE" width="1000" llx="36" lly="-19" urx="965" ury="737"/> + <char name="Oacute" width="778" llx="39" lly="-19" urx="739" ury="929"/> + <char name="Ocircumflex" width="778" llx="39" lly="-19" urx="739" ury="929"/> + <char name="Odieresis" width="778" llx="39" lly="-19" urx="739" ury="901"/> + <char name="Ograve" width="778" llx="39" lly="-19" urx="739" ury="929"/> + <char name="Oslash" width="778" llx="39" lly="-19" urx="740" ury="737"/> + <char name="Otilde" width="778" llx="39" lly="-19" urx="739" ury="917"/> + <char name="P" width="667" llx="86" lly="0" urx="622" ury="718"/> + <char name="Q" width="778" llx="39" lly="-56" urx="739" ury="737"/> + <char name="R" width="722" llx="88" lly="0" urx="684" ury="718"/> + <char name="S" width="667" llx="49" lly="-19" urx="620" ury="737"/> + <char name="Scaron" width="667" llx="49" lly="-19" urx="620" ury="929"/> + <char name="T" width="611" llx="14" lly="0" urx="597" ury="718"/> + <char name="Thorn" width="667" llx="86" lly="0" urx="622" ury="718"/> + <char name="U" width="722" llx="79" lly="-19" urx="644" ury="718"/> + <char name="Uacute" width="722" llx="79" lly="-19" urx="644" ury="929"/> + <char name="Ucircumflex" width="722" llx="79" lly="-19" urx="644" ury="929"/> + <char name="Udieresis" width="722" llx="79" lly="-19" urx="644" ury="901"/> + <char name="Ugrave" width="722" llx="79" lly="-19" urx="644" ury="929"/> + <char name="V" width="667" llx="20" lly="0" urx="647" ury="718"/> + <char name="W" width="944" llx="16" lly="0" urx="928" ury="718"/> + <char name="X" width="667" llx="19" lly="0" urx="648" ury="718"/> + <char name="Y" width="667" llx="14" lly="0" urx="653" ury="718"/> + <char name="Yacute" width="667" llx="14" lly="0" urx="653" ury="929"/> + <char name="Ydieresis" width="667" llx="14" lly="0" urx="653" ury="901"/> + <char name="Z" width="611" llx="23" lly="0" urx="588" ury="718"/> + <char name="Zcaron" width="611" llx="23" lly="0" urx="588" ury="929"/> + <char name="a" width="556" llx="36" lly="-15" urx="530" ury="538"/> + <char name="aacute" width="556" llx="36" lly="-15" urx="530" ury="734"/> + <char name="acircumflex" width="556" llx="36" lly="-15" urx="530" ury="734"/> + <char name="acute" width="333" llx="122" lly="593" urx="319" ury="734"/> + <char name="adieresis" width="556" llx="36" lly="-15" urx="530" ury="706"/> + <char name="ae" width="889" llx="36" lly="-15" urx="847" ury="538"/> + <char name="agrave" width="556" llx="36" lly="-15" urx="530" ury="734"/> + <char name="ampersand" width="667" llx="44" lly="-15" urx="645" ury="718"/> + <char name="aring" width="556" llx="36" lly="-15" urx="530" ury="756"/> + <char name="asciicircum" width="469" llx="-14" lly="264" urx="483" ury="688"/> + <char name="asciitilde" width="584" llx="61" lly="180" urx="523" ury="326"/> + <char name="asterisk" width="389" llx="39" lly="431" urx="349" ury="718"/> + <char name="at" width="1015" llx="147" lly="-19" urx="868" ury="737"/> + <char name="atilde" width="556" llx="36" lly="-15" urx="530" ury="722"/> + <char name="b" width="556" llx="58" lly="-15" urx="517" ury="718"/> + <char name="backslash" width="278" llx="-17" lly="-19" urx="295" ury="737"/> + <char name="bar" width="260" llx="94" lly="-225" urx="167" ury="775"/> + <char name="braceleft" width="334" llx="42" lly="-196" urx="292" ury="722"/> + <char name="braceright" width="334" llx="42" lly="-196" urx="292" ury="722"/> + <char name="bracketleft" width="278" llx="63" lly="-196" urx="250" ury="722"/> + <char name="bracketright" width="278" llx="28" lly="-196" urx="215" ury="722"/> + <char name="breve" width="333" llx="13" lly="595" urx="321" ury="731"/> + <char name="brokenbar" width="260" llx="94" lly="-150" urx="167" ury="700"/> + <char name="bullet" width="350" llx="18" lly="202" urx="333" ury="517"/> + <char name="c" width="500" llx="30" lly="-15" urx="477" ury="538"/> + <char name="caron" width="333" llx="21" lly="593" urx="312" ury="734"/> + <char name="ccedilla" width="500" llx="30" lly="-225" urx="477" ury="538"/> + <char name="cedilla" width="333" llx="45" lly="-225" urx="259" ury="0"/> + <char name="cent" width="556" llx="51" lly="-115" urx="513" ury="623"/> + <char name="circumflex" width="333" llx="21" lly="593" urx="312" ury="734"/> + <char name="colon" width="278" llx="87" lly="0" urx="191" ury="516"/> + <char name="comma" width="278" llx="87" lly="-147" urx="191" ury="106"/> + <char name="copyright" width="737" llx="-14" lly="-19" urx="752" ury="737"/> + <char name="currency" width="556" llx="28" lly="99" urx="528" ury="603"/> + <char name="d" width="556" llx="35" lly="-15" urx="499" ury="718"/> + <char name="dagger" width="556" llx="43" lly="-159" urx="514" ury="718"/> + <char name="daggerdbl" width="556" llx="43" lly="-159" urx="514" ury="718"/> + <char name="degree" width="400" llx="54" lly="411" urx="346" ury="703"/> + <char name="dieresis" width="333" llx="40" lly="604" urx="293" ury="706"/> + <char name="divide" width="584" llx="39" lly="-19" urx="545" ury="524"/> + <char name="dollar" width="556" llx="32" lly="-115" urx="520" ury="775"/> + <char name="dotaccent" width="333" llx="121" lly="604" urx="212" ury="706"/> + <char name="dotlessi" width="278" llx="95" lly="0" urx="183" ury="523"/> + <char name="e" width="556" llx="40" lly="-15" urx="516" ury="538"/> + <char name="eacute" width="556" llx="40" lly="-15" urx="516" ury="734"/> + <char name="ecircumflex" width="556" llx="40" lly="-15" urx="516" ury="734"/> + <char name="edieresis" width="556" llx="40" lly="-15" urx="516" ury="706"/> + <char name="egrave" width="556" llx="40" lly="-15" urx="516" ury="734"/> + <char name="eight" width="556" llx="38" lly="-19" urx="517" ury="703"/> + <char name="ellipsis" width="1000" llx="115" lly="0" urx="885" ury="106"/> + <char name="emdash" width="1000" llx="0" lly="240" urx="1000" ury="313"/> + <char name="endash" width="556" llx="0" lly="240" urx="556" ury="313"/> + <char name="equal" width="584" llx="39" lly="115" urx="545" ury="390"/> + <char name="eth" width="556" llx="35" lly="-15" urx="522" ury="737"/> + <char name="exclam" width="278" llx="90" lly="0" urx="187" ury="718"/> + <char name="exclamdown" width="333" llx="118" lly="-195" urx="215" ury="523"/> + <char name="f" width="278" llx="14" lly="0" urx="262" ury="728"/> + <char name="fi" width="500" llx="14" lly="0" urx="434" ury="728"/> + <char name="five" width="556" llx="32" lly="-19" urx="514" ury="688"/> + <char name="fl" width="500" llx="14" lly="0" urx="432" ury="728"/> + <char name="florin" width="556" llx="-11" lly="-207" urx="501" ury="737"/> + <char name="four" width="556" llx="25" lly="0" urx="523" ury="703"/> + <char name="fraction" width="167" llx="-166" lly="-19" urx="333" ury="703"/> + <char name="g" width="556" llx="40" lly="-220" urx="499" ury="538"/> + <char name="germandbls" width="611" llx="67" lly="-15" urx="571" ury="728"/> + <char name="grave" width="333" llx="14" lly="593" urx="211" ury="734"/> + <char name="greater" width="584" llx="48" lly="11" urx="536" ury="495"/> + <char name="guillemotleft" width="556" llx="97" lly="108" urx="459" ury="446"/> + <char name="guillemotright" width="556" llx="97" lly="108" urx="459" ury="446"/> + <char name="guilsinglleft" width="333" llx="88" lly="108" urx="245" ury="446"/> + <char name="guilsinglright" width="333" llx="88" lly="108" urx="245" ury="446"/> + <char name="h" width="556" llx="65" lly="0" urx="491" ury="718"/> + <char name="hungarumlaut" width="333" llx="31" lly="593" urx="409" ury="734"/> + <char name="hyphen" width="333" llx="44" lly="232" urx="289" ury="322"/> + <char name="i" width="222" llx="67" lly="0" urx="155" ury="718"/> + <char name="iacute" width="278" llx="95" lly="0" urx="292" ury="734"/> + <char name="icircumflex" width="278" llx="-6" lly="0" urx="285" ury="734"/> + <char name="idieresis" width="278" llx="13" lly="0" urx="266" ury="706"/> + <char name="igrave" width="278" llx="-13" lly="0" urx="184" ury="734"/> + <char name="j" width="222" llx="-16" lly="-210" urx="155" ury="718"/> + <char name="k" width="500" llx="67" lly="0" urx="501" ury="718"/> + <char name="l" width="222" llx="67" lly="0" urx="155" ury="718"/> + <char name="less" width="584" llx="48" lly="11" urx="536" ury="495"/> + <char name="logicalnot" width="584" llx="39" lly="108" urx="545" ury="390"/> + <char name="lslash" width="222" llx="-20" lly="0" urx="242" ury="718"/> + <char name="m" width="833" llx="65" lly="0" urx="769" ury="538"/> + <char name="macron" width="333" llx="10" lly="627" urx="323" ury="684"/> + <char name="minus" width="324" llx="39" lly="216" urx="545" ury="289"/> + <char name="mu" width="556" llx="68" lly="-207" urx="489" ury="523"/> + <char name="multiply" width="584" llx="39" lly="0" urx="545" ury="506"/> + <char name="n" width="556" llx="65" lly="0" urx="491" ury="538"/> + <char name="nine" width="556" llx="42" lly="-19" urx="514" ury="703"/> + <char name="ntilde" width="556" llx="65" lly="0" urx="491" ury="722"/> + <char name="numbersign" width="556" llx="28" lly="0" urx="529" ury="688"/> + <char name="o" width="556" llx="35" lly="-14" urx="521" ury="538"/> + <char name="oacute" width="556" llx="35" lly="-14" urx="521" ury="734"/> + <char name="ocircumflex" width="556" llx="35" lly="-14" urx="521" ury="734"/> + <char name="odieresis" width="556" llx="35" lly="-14" urx="521" ury="706"/> + <char name="oe" width="944" llx="35" lly="-15" urx="902" ury="538"/> + <char name="ogonek" width="333" llx="73" lly="-225" urx="287" ury="0"/> + <char name="ograve" width="556" llx="35" lly="-14" urx="521" ury="734"/> + <char name="one" width="556" llx="101" lly="0" urx="359" ury="703"/> + <char name="onehalf" width="834" llx="43" lly="-19" urx="773" ury="703"/> + <char name="onequarter" width="834" llx="73" lly="-19" urx="756" ury="703"/> + <char name="onesuperior" width="333" llx="43" lly="281" urx="222" ury="703"/> + <char name="ordfeminine" width="370" llx="24" lly="405" urx="346" ury="737"/> + <char name="ordmasculine" width="365" llx="25" lly="405" urx="341" ury="737"/> + <char name="oslash" width="611" llx="28" lly="-22" urx="537" ury="545"/> + <char name="otilde" width="556" llx="35" lly="-14" urx="521" ury="722"/> + <char name="p" width="556" llx="58" lly="-207" urx="517" ury="538"/> + <char name="paragraph" width="537" llx="18" lly="-173" urx="497" ury="718"/> + <char name="parenleft" width="333" llx="68" lly="-207" urx="299" ury="733"/> + <char name="parenright" width="333" llx="34" lly="-207" urx="265" ury="733"/> + <char name="percent" width="889" llx="39" lly="-19" urx="850" ury="703"/> + <char name="period" width="278" llx="87" lly="0" urx="191" ury="106"/> + <char name="periodcentered" width="278" llx="77" lly="190" urx="202" ury="315"/> + <char name="perthousand" width="1000" llx="7" lly="-19" urx="994" ury="703"/> + <char name="plus" width="584" llx="39" lly="0" urx="545" ury="505"/> + <char name="plusminus" width="584" llx="39" lly="0" urx="545" ury="506"/> + <char name="q" width="556" llx="35" lly="-207" urx="494" ury="538"/> + <char name="question" width="556" llx="56" lly="0" urx="492" ury="727"/> + <char name="questiondown" width="611" llx="91" lly="-201" urx="527" ury="525"/> + <char name="quotedbl" width="355" llx="70" lly="463" urx="285" ury="718"/> + <char name="quotedblbase" width="333" llx="26" lly="-149" urx="295" ury="106"/> + <char name="quotedblleft" width="333" llx="38" lly="470" urx="307" ury="725"/> + <char name="quotedblright" width="333" llx="26" lly="463" urx="295" ury="718"/> + <char name="quoteleft" width="222" llx="65" lly="470" urx="169" ury="725"/> + <char name="quoteright" width="222" llx="53" lly="463" urx="157" ury="718"/> + <char name="quotesinglbase" width="222" llx="53" lly="-149" urx="157" ury="106"/> + <char name="quotesingle" width="191" llx="59" lly="463" urx="132" ury="718"/> + <char name="r" width="333" llx="77" lly="0" urx="332" ury="538"/> + <char name="registered" width="737" llx="-14" lly="-19" urx="752" ury="737"/> + <char name="ring" width="333" llx="75" lly="572" urx="259" ury="756"/> + <char name="s" width="500" llx="32" lly="-15" urx="464" ury="538"/> + <char name="scaron" width="500" llx="32" lly="-15" urx="464" ury="734"/> + <char name="section" width="556" llx="43" lly="-191" urx="512" ury="737"/> + <char name="semicolon" width="278" llx="87" lly="-147" urx="191" ury="516"/> + <char name="seven" width="556" llx="37" lly="0" urx="523" ury="688"/> + <char name="six" width="556" llx="38" lly="-19" urx="518" ury="703"/> + <char name="slash" width="278" llx="-17" lly="-19" urx="295" ury="737"/> + <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="278"/> - <char name="sterling" width="556"/> - <char name="t" width="278"/> - <char name="thorn" width="556"/> - <char name="three" width="556"/> - <char name="threequarters" width="834"/> - <char name="threesuperior" width="333"/> - <char name="tilde" width="333"/> - <char name="trademark" width="1000"/> - <char name="two" width="556"/> - <char name="twosuperior" width="333"/> - <char name="u" width="556"/> - <char name="uacute" width="556"/> - <char name="ucircumflex" width="556"/> - <char name="udieresis" width="556"/> - <char name="ugrave" width="556"/> - <char name="underscore" width="556"/> - <char name="v" width="500"/> - <char name="w" width="722"/> - <char name="x" width="500"/> - <char name="y" width="500"/> - <char name="yacute" width="500"/> - <char name="ydieresis" width="500"/> - <char name="yen" width="556"/> - <char name="z" width="500"/> - <char name="zcaron" width="500"/> - <char name="zero" width="556"/> - </widths> + <char name="sterling" width="556" llx="33" lly="-16" urx="539" ury="718"/> + <char name="t" width="278" llx="14" lly="-7" urx="257" ury="669"/> + <char name="thorn" width="556" llx="58" lly="-207" urx="517" ury="718"/> + <char name="three" width="556" llx="34" lly="-19" urx="522" ury="703"/> + <char name="threequarters" width="834" llx="45" lly="-19" urx="810" ury="703"/> + <char name="threesuperior" width="333" llx="5" lly="270" urx="325" ury="703"/> + <char name="tilde" width="333" llx="-4" lly="606" urx="337" ury="722"/> + <char name="trademark" width="1000" llx="46" lly="306" urx="903" ury="718"/> + <char name="two" width="556" llx="26" lly="0" urx="507" ury="703"/> + <char name="twosuperior" width="333" llx="4" lly="281" urx="323" ury="703"/> + <char name="u" width="556" llx="68" lly="-15" urx="489" ury="523"/> + <char name="uacute" width="556" llx="68" lly="-15" urx="489" ury="734"/> + <char name="ucircumflex" width="556" llx="68" lly="-15" urx="489" ury="734"/> + <char name="udieresis" width="556" llx="68" lly="-15" urx="489" ury="706"/> + <char name="ugrave" width="556" llx="68" lly="-15" urx="489" ury="734"/> + <char name="underscore" width="556" llx="0" lly="-125" urx="556" ury="-75"/> + <char name="v" width="500" llx="8" lly="0" urx="492" ury="523"/> + <char name="w" width="722" llx="14" lly="0" urx="709" ury="523"/> + <char name="x" width="500" llx="11" lly="0" urx="490" ury="523"/> + <char name="y" width="500" llx="11" lly="-214" urx="489" ury="523"/> + <char name="yacute" width="500" llx="11" lly="-214" urx="489" ury="734"/> + <char name="ydieresis" width="500" llx="11" lly="-214" urx="489" ury="706"/> + <char name="yen" width="556" llx="3" lly="0" urx="553" ury="688"/> + <char name="z" width="500" llx="31" lly="0" urx="469" ury="523"/> + <char name="zcaron" width="500" llx="31" lly="0" urx="469" ury="734"/> + <char name="zero" width="556" llx="37" lly="-19" urx="519" ury="703"/> + </char-metrics> <kerning kpx1="107"> <pair kern="-20" kpx2="111"/> <pair kern="-20" kpx2="101"/> diff --git a/src/codegen/fonts/HelveticaBold.xml b/src/codegen/fonts/HelveticaBold.xml index 2620a128e..4efd01f22 100644 --- a/src/codegen/fonts/HelveticaBold.xml +++ b/src/codegen/fonts/HelveticaBold.xml @@ -22,245 +22,246 @@ <family-name>Helvetica</family-name> <class-name>HelveticaBold</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>718</cap-height> <x-height>532</x-height> <ascender>718</ascender> <descender>-207</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="722"/> - <char name="AE" width="1000"/> - <char name="Aacute" width="722"/> - <char name="Acircumflex" width="722"/> - <char name="Adieresis" width="722"/> - <char name="Agrave" width="722"/> - <char name="Aring" width="722"/> - <char name="Atilde" width="722"/> - <char name="B" width="722"/> - <char name="C" width="722"/> - <char name="Ccedilla" width="722"/> - <char name="D" width="722"/> - <char name="E" width="667"/> - <char name="Eacute" width="667"/> - <char name="Ecircumflex" width="667"/> - <char name="Edieresis" width="667"/> - <char name="Egrave" width="667"/> - <char name="Eth" width="722"/> - <char name="Euro" width="556"/> - <char name="F" width="611"/> - <char name="G" width="778"/> - <char name="H" width="722"/> - <char name="I" width="278"/> - <char name="Iacute" width="278"/> - <char name="Icircumflex" width="278"/> - <char name="Idieresis" width="278"/> - <char name="Igrave" width="278"/> - <char name="J" width="556"/> - <char name="K" width="722"/> - <char name="L" width="611"/> - <char name="Lslash" width="611"/> - <char name="M" width="833"/> - <char name="N" width="722"/> - <char name="Ntilde" width="722"/> - <char name="O" width="778"/> - <char name="OE" width="1000"/> - <char name="Oacute" width="778"/> - <char name="Ocircumflex" width="778"/> - <char name="Odieresis" width="778"/> - <char name="Ograve" width="778"/> - <char name="Oslash" width="778"/> - <char name="Otilde" width="778"/> - <char name="P" width="667"/> - <char name="Q" width="778"/> - <char name="R" width="722"/> - <char name="S" width="667"/> - <char name="Scaron" width="667"/> - <char name="T" width="611"/> - <char name="Thorn" width="667"/> - <char name="U" width="722"/> - <char name="Uacute" width="722"/> - <char name="Ucircumflex" width="722"/> - <char name="Udieresis" width="722"/> - <char name="Ugrave" width="722"/> - <char name="V" width="667"/> - <char name="W" width="944"/> - <char name="X" width="667"/> - <char name="Y" width="667"/> - <char name="Yacute" width="667"/> - <char name="Ydieresis" width="667"/> - <char name="Z" width="611"/> - <char name="Zcaron" width="611"/> - <char name="a" width="556"/> - <char name="aacute" width="556"/> - <char name="acircumflex" width="556"/> - <char name="acute" width="333"/> - <char name="adieresis" width="556"/> - <char name="ae" width="889"/> - <char name="agrave" width="556"/> - <char name="ampersand" width="722"/> - <char name="aring" width="556"/> - <char name="asciicircum" width="584"/> - <char name="asciitilde" width="584"/> - <char name="asterisk" width="389"/> - <char name="at" width="975"/> - <char name="atilde" width="556"/> - <char name="b" width="611"/> - <char name="backslash" width="278"/> - <char name="bar" width="280"/> - <char name="braceleft" width="389"/> - <char name="braceright" width="389"/> - <char name="bracketleft" width="333"/> - <char name="bracketright" width="333"/> - <char name="breve" width="333"/> - <char name="brokenbar" width="280"/> - <char name="bullet" width="350"/> - <char name="c" width="556"/> - <char name="caron" width="333"/> - <char name="ccedilla" width="556"/> - <char name="cedilla" width="333"/> - <char name="cent" width="556"/> - <char name="circumflex" width="333"/> - <char name="colon" width="333"/> - <char name="comma" width="278"/> - <char name="copyright" width="737"/> - <char name="currency" width="556"/> - <char name="d" width="611"/> - <char name="dagger" width="556"/> - <char name="daggerdbl" width="556"/> - <char name="degree" width="400"/> - <char name="dieresis" width="333"/> - <char name="divide" width="584"/> - <char name="dollar" width="556"/> - <char name="dotaccent" width="333"/> - <char name="dotlessi" width="278"/> - <char name="e" width="556"/> - <char name="eacute" width="556"/> - <char name="ecircumflex" width="556"/> - <char name="edieresis" width="556"/> - <char name="egrave" width="556"/> - <char name="eight" width="556"/> - <char name="ellipsis" width="1000"/> - <char name="emdash" width="1000"/> - <char name="endash" width="556"/> - <char name="equal" width="584"/> - <char name="eth" width="611"/> - <char name="exclam" width="333"/> - <char name="exclamdown" width="333"/> - <char name="f" width="333"/> - <char name="fi" width="611"/> - <char name="five" width="556"/> - <char name="fl" width="611"/> - <char name="florin" width="556"/> - <char name="four" width="556"/> - <char name="fraction" width="167"/> - <char name="g" width="611"/> - <char name="germandbls" width="611"/> - <char name="grave" width="333"/> - <char name="greater" width="584"/> - <char name="guillemotleft" width="556"/> - <char name="guillemotright" width="556"/> - <char name="guilsinglleft" width="333"/> - <char name="guilsinglright" width="333"/> - <char name="h" width="611"/> - <char name="hungarumlaut" width="333"/> - <char name="hyphen" width="333"/> - <char name="i" width="278"/> - <char name="iacute" width="278"/> - <char name="icircumflex" width="278"/> - <char name="idieresis" width="278"/> - <char name="igrave" width="278"/> - <char name="j" width="278"/> - <char name="k" width="556"/> - <char name="l" width="278"/> - <char name="less" width="584"/> - <char name="logicalnot" width="584"/> - <char name="lslash" width="278"/> - <char name="m" width="889"/> - <char name="macron" width="333"/> - <char name="minus" width="324"/> - <char name="mu" width="611"/> - <char name="multiply" width="584"/> - <char name="n" width="611"/> - <char name="nine" width="556"/> - <char name="ntilde" width="611"/> - <char name="numbersign" width="556"/> - <char name="o" width="611"/> - <char name="oacute" width="611"/> - <char name="ocircumflex" width="611"/> - <char name="odieresis" width="611"/> - <char name="oe" width="944"/> - <char name="ogonek" width="333"/> - <char name="ograve" width="611"/> - <char name="one" width="556"/> - <char name="onehalf" width="834"/> - <char name="onequarter" width="834"/> - <char name="onesuperior" width="333"/> - <char name="ordfeminine" width="370"/> - <char name="ordmasculine" width="365"/> - <char name="oslash" width="611"/> - <char name="otilde" width="611"/> - <char name="p" width="611"/> - <char name="paragraph" width="556"/> - <char name="parenleft" width="333"/> - <char name="parenright" width="333"/> - <char name="percent" width="889"/> - <char name="period" width="278"/> - <char name="periodcentered" width="278"/> - <char name="perthousand" width="1000"/> - <char name="plus" width="584"/> - <char name="plusminus" width="584"/> - <char name="q" width="611"/> - <char name="question" width="611"/> - <char name="questiondown" width="611"/> - <char name="quotedbl" width="474"/> - <char name="quotedblbase" width="500"/> - <char name="quotedblleft" width="500"/> - <char name="quotedblright" width="500"/> - <char name="quoteleft" width="278"/> - <char name="quoteright" width="278"/> - <char name="quotesinglbase" width="278"/> - <char name="quotesingle" width="238"/> - <char name="r" width="389"/> - <char name="registered" width="737"/> - <char name="ring" width="333"/> - <char name="s" width="556"/> - <char name="scaron" width="556"/> - <char name="section" width="556"/> - <char name="semicolon" width="333"/> - <char name="seven" width="556"/> - <char name="six" width="556"/> - <char name="slash" width="278"/> - <char name="space" width="278"/> + <char-metrics> + <char name="A" width="722" llx="20" lly="0" urx="702" ury="718"/> + <char name="AE" width="1000" llx="5" lly="0" urx="954" ury="718"/> + <char name="Aacute" width="722" llx="20" lly="0" urx="702" ury="936"/> + <char name="Acircumflex" width="722" llx="20" lly="0" urx="702" ury="936"/> + <char name="Adieresis" width="722" llx="20" lly="0" urx="702" ury="915"/> + <char name="Agrave" width="722" llx="20" lly="0" urx="702" ury="936"/> + <char name="Aring" width="722" llx="20" lly="0" urx="702" ury="962"/> + <char name="Atilde" width="722" llx="20" lly="0" urx="702" ury="923"/> + <char name="B" width="722" llx="76" lly="0" urx="669" ury="718"/> + <char name="C" width="722" llx="44" lly="-19" urx="684" ury="737"/> + <char name="Ccedilla" width="722" llx="44" lly="-228" urx="684" ury="737"/> + <char name="D" width="722" llx="76" lly="0" urx="685" ury="718"/> + <char name="E" width="667" llx="76" lly="0" urx="621" ury="718"/> + <char name="Eacute" width="667" llx="76" lly="0" urx="621" ury="936"/> + <char name="Ecircumflex" width="667" llx="76" lly="0" urx="621" ury="936"/> + <char name="Edieresis" width="667" llx="76" lly="0" urx="621" ury="915"/> + <char name="Egrave" width="667" llx="76" lly="0" urx="621" ury="936"/> + <char name="Eth" width="722" llx="-5" lly="0" urx="685" ury="718"/> + <char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="611" llx="76" lly="0" urx="587" ury="718"/> + <char name="G" width="778" llx="44" lly="-19" urx="713" ury="737"/> + <char name="H" width="722" llx="71" lly="0" urx="651" ury="718"/> + <char name="I" width="278" llx="64" lly="0" urx="214" ury="718"/> + <char name="Iacute" width="278" llx="64" lly="0" urx="329" ury="936"/> + <char name="Icircumflex" width="278" llx="-37" lly="0" urx="316" ury="936"/> + <char name="Idieresis" width="278" llx="-21" lly="0" urx="300" ury="915"/> + <char name="Igrave" width="278" llx="-50" lly="0" urx="214" ury="936"/> + <char name="J" width="556" llx="22" lly="-18" urx="484" ury="718"/> + <char name="K" width="722" llx="87" lly="0" urx="722" ury="718"/> + <char name="L" width="611" llx="76" lly="0" urx="583" ury="718"/> + <char name="Lslash" width="611" llx="-20" lly="0" urx="583" ury="718"/> + <char name="M" width="833" llx="69" lly="0" urx="765" ury="718"/> + <char name="N" width="722" llx="69" lly="0" urx="654" ury="718"/> + <char name="Ntilde" width="722" llx="69" lly="0" urx="654" ury="923"/> + <char name="O" width="778" llx="44" lly="-19" urx="734" ury="737"/> + <char name="OE" width="1000" llx="37" lly="-19" urx="961" ury="737"/> + <char name="Oacute" width="778" llx="44" lly="-19" urx="734" ury="936"/> + <char name="Ocircumflex" width="778" llx="44" lly="-19" urx="734" ury="936"/> + <char name="Odieresis" width="778" llx="44" lly="-19" urx="734" ury="915"/> + <char name="Ograve" width="778" llx="44" lly="-19" urx="734" ury="936"/> + <char name="Oslash" width="778" llx="33" lly="-27" urx="744" ury="745"/> + <char name="Otilde" width="778" llx="44" lly="-19" urx="734" ury="923"/> + <char name="P" width="667" llx="76" lly="0" urx="627" ury="718"/> + <char name="Q" width="778" llx="44" lly="-52" urx="737" ury="737"/> + <char name="R" width="722" llx="76" lly="0" urx="677" ury="718"/> + <char name="S" width="667" llx="39" lly="-19" urx="629" ury="737"/> + <char name="Scaron" width="667" llx="39" lly="-19" urx="629" ury="936"/> + <char name="T" width="611" llx="14" lly="0" urx="598" ury="718"/> + <char name="Thorn" width="667" llx="76" lly="0" urx="627" ury="718"/> + <char name="U" width="722" llx="72" lly="-19" urx="651" ury="718"/> + <char name="Uacute" width="722" llx="72" lly="-19" urx="651" ury="936"/> + <char name="Ucircumflex" width="722" llx="72" lly="-19" urx="651" ury="936"/> + <char name="Udieresis" width="722" llx="72" lly="-19" urx="651" ury="915"/> + <char name="Ugrave" width="722" llx="72" lly="-19" urx="651" ury="936"/> + <char name="V" width="667" llx="19" lly="0" urx="648" ury="718"/> + <char name="W" width="944" llx="16" lly="0" urx="929" ury="718"/> + <char name="X" width="667" llx="14" lly="0" urx="653" ury="718"/> + <char name="Y" width="667" llx="15" lly="0" urx="653" ury="718"/> + <char name="Yacute" width="667" llx="15" lly="0" urx="653" ury="936"/> + <char name="Ydieresis" width="667" llx="15" lly="0" urx="653" ury="915"/> + <char name="Z" width="611" llx="25" lly="0" urx="586" ury="718"/> + <char name="Zcaron" width="611" llx="25" lly="0" urx="586" ury="936"/> + <char name="a" width="556" llx="29" lly="-14" urx="527" ury="546"/> + <char name="aacute" width="556" llx="29" lly="-14" urx="527" ury="750"/> + <char name="acircumflex" width="556" llx="29" lly="-14" urx="527" ury="750"/> + <char name="acute" width="333" llx="108" lly="604" urx="356" ury="750"/> + <char name="adieresis" width="556" llx="29" lly="-14" urx="527" ury="729"/> + <char name="ae" width="889" llx="29" lly="-14" urx="858" ury="546"/> + <char name="agrave" width="556" llx="29" lly="-14" urx="527" ury="750"/> + <char name="ampersand" width="722" llx="54" lly="-19" urx="701" ury="718"/> + <char name="aring" width="556" llx="29" lly="-14" urx="527" ury="776"/> + <char name="asciicircum" width="584" llx="62" lly="323" urx="522" ury="698"/> + <char name="asciitilde" width="584" llx="61" lly="163" urx="523" ury="343"/> + <char name="asterisk" width="389" llx="27" lly="387" urx="362" ury="718"/> + <char name="at" width="975" llx="118" lly="-19" urx="856" ury="737"/> + <char name="atilde" width="556" llx="29" lly="-14" urx="527" ury="737"/> + <char name="b" width="611" llx="61" lly="-14" urx="578" ury="718"/> + <char name="backslash" width="278" llx="-33" lly="-19" urx="311" ury="737"/> + <char name="bar" width="280" llx="84" lly="-225" urx="196" ury="775"/> + <char name="braceleft" width="389" llx="48" lly="-196" urx="365" ury="722"/> + <char name="braceright" width="389" llx="24" lly="-196" urx="341" ury="722"/> + <char name="bracketleft" width="333" llx="63" lly="-196" urx="309" ury="722"/> + <char name="bracketright" width="333" llx="24" lly="-196" urx="270" ury="722"/> + <char name="breve" width="333" llx="-2" lly="604" urx="335" ury="750"/> + <char name="brokenbar" width="280" llx="84" lly="-150" urx="196" ury="700"/> + <char name="bullet" width="350" llx="10" lly="194" urx="340" ury="524"/> + <char name="c" width="556" llx="34" lly="-14" urx="524" ury="546"/> + <char name="caron" width="333" llx="-10" lly="604" urx="343" ury="750"/> + <char name="ccedilla" width="556" llx="34" lly="-228" urx="524" ury="546"/> + <char name="cedilla" width="333" llx="6" lly="-228" urx="245" ury="0"/> + <char name="cent" width="556" llx="34" lly="-118" urx="524" ury="628"/> + <char name="circumflex" width="333" llx="-10" lly="604" urx="343" ury="750"/> + <char name="colon" width="333" llx="92" lly="0" urx="242" ury="512"/> + <char name="comma" width="278" llx="64" lly="-168" urx="214" ury="146"/> + <char name="copyright" width="737" llx="-11" lly="-19" urx="749" ury="737"/> + <char name="currency" width="556" llx="-3" lly="76" urx="559" ury="636"/> + <char name="d" width="611" llx="34" lly="-14" urx="551" ury="718"/> + <char name="dagger" width="556" llx="36" lly="-171" urx="520" ury="718"/> + <char name="daggerdbl" width="556" llx="36" lly="-171" urx="520" ury="718"/> + <char name="degree" width="400" llx="57" lly="426" urx="343" ury="712"/> + <char name="dieresis" width="333" llx="6" lly="614" urx="327" ury="729"/> + <char name="divide" width="584" llx="40" lly="-42" urx="544" ury="548"/> + <char name="dollar" width="556" llx="30" lly="-115" urx="523" ury="775"/> + <char name="dotaccent" width="333" llx="104" lly="614" urx="230" ury="729"/> + <char name="dotlessi" width="278" llx="69" lly="0" urx="209" ury="532"/> + <char name="e" width="556" llx="23" lly="-14" urx="528" ury="546"/> + <char name="eacute" width="556" llx="23" lly="-14" urx="528" ury="750"/> + <char name="ecircumflex" width="556" llx="23" lly="-14" urx="528" ury="750"/> + <char name="edieresis" width="556" llx="23" lly="-14" urx="528" ury="729"/> + <char name="egrave" width="556" llx="23" lly="-14" urx="528" ury="750"/> + <char name="eight" width="556" llx="32" lly="-19" urx="524" ury="710"/> + <char name="ellipsis" width="1000" llx="92" lly="0" urx="908" ury="146"/> + <char name="emdash" width="1000" llx="0" lly="227" urx="1000" ury="333"/> + <char name="endash" width="556" llx="0" lly="227" urx="556" ury="333"/> + <char name="equal" width="584" llx="40" lly="87" urx="544" ury="419"/> + <char name="eth" width="611" llx="34" lly="-14" urx="578" ury="737"/> + <char name="exclam" width="333" llx="90" lly="0" urx="244" ury="718"/> + <char name="exclamdown" width="333" llx="90" lly="-186" urx="244" ury="532"/> + <char name="f" width="333" llx="10" lly="0" urx="318" ury="727"/> + <char name="fi" width="611" llx="10" lly="0" urx="542" ury="727"/> + <char name="five" width="556" llx="27" lly="-19" urx="516" ury="698"/> + <char name="fl" width="611" llx="10" lly="0" urx="542" ury="727"/> + <char name="florin" width="556" llx="-10" lly="-210" urx="516" ury="737"/> + <char name="four" width="556" llx="27" lly="0" urx="526" ury="710"/> + <char name="fraction" width="167" llx="-170" lly="-19" urx="336" ury="710"/> + <char name="g" width="611" llx="40" lly="-217" urx="553" ury="546"/> + <char name="germandbls" width="611" llx="69" lly="-14" urx="579" ury="731"/> + <char name="grave" width="333" llx="-23" lly="604" urx="225" ury="750"/> + <char name="greater" width="584" llx="38" lly="-8" urx="546" ury="514"/> + <char name="guillemotleft" width="556" llx="88" lly="76" urx="468" ury="484"/> + <char name="guillemotright" width="556" llx="88" lly="76" urx="468" ury="484"/> + <char name="guilsinglleft" width="333" llx="83" lly="76" urx="250" ury="484"/> + <char name="guilsinglright" width="333" llx="83" lly="76" urx="250" ury="484"/> + <char name="h" width="611" llx="65" lly="0" urx="546" ury="718"/> + <char name="hungarumlaut" width="333" llx="9" lly="604" urx="486" ury="750"/> + <char name="hyphen" width="333" llx="27" lly="215" urx="306" ury="345"/> + <char name="i" width="278" llx="69" lly="0" urx="209" ury="725"/> + <char name="iacute" width="278" llx="69" lly="0" urx="329" ury="750"/> + <char name="icircumflex" width="278" llx="-37" lly="0" urx="316" ury="750"/> + <char name="idieresis" width="278" llx="-21" lly="0" urx="300" ury="729"/> + <char name="igrave" width="278" llx="-50" lly="0" urx="209" ury="750"/> + <char name="j" width="278" llx="3" lly="-214" urx="209" ury="725"/> + <char name="k" width="556" llx="69" lly="0" urx="562" ury="718"/> + <char name="l" width="278" llx="69" lly="0" urx="209" ury="718"/> + <char name="less" width="584" llx="38" lly="-8" urx="546" ury="514"/> + <char name="logicalnot" width="584" llx="40" lly="108" urx="544" ury="419"/> + <char name="lslash" width="278" llx="-18" lly="0" urx="296" ury="718"/> + <char name="m" width="889" llx="64" lly="0" urx="826" ury="546"/> + <char name="macron" width="333" llx="-6" lly="604" urx="339" ury="678"/> + <char name="minus" width="324" llx="40" lly="197" urx="544" ury="309"/> + <char name="mu" width="611" llx="66" lly="-207" urx="545" ury="532"/> + <char name="multiply" width="584" llx="40" lly="1" urx="545" ury="505"/> + <char name="n" width="611" llx="65" lly="0" urx="546" ury="546"/> + <char name="nine" width="556" llx="30" lly="-19" urx="522" ury="710"/> + <char name="ntilde" width="611" llx="65" lly="0" urx="546" ury="737"/> + <char name="numbersign" width="556" llx="18" lly="0" urx="538" ury="698"/> + <char name="o" width="611" llx="34" lly="-14" urx="578" ury="546"/> + <char name="oacute" width="611" llx="34" lly="-14" urx="578" ury="750"/> + <char name="ocircumflex" width="611" llx="34" lly="-14" urx="578" ury="750"/> + <char name="odieresis" width="611" llx="34" lly="-14" urx="578" ury="729"/> + <char name="oe" width="944" llx="34" lly="-14" urx="912" ury="546"/> + <char name="ogonek" width="333" llx="71" lly="-228" urx="304" ury="0"/> + <char name="ograve" width="611" llx="34" lly="-14" urx="578" ury="750"/> + <char name="one" width="556" llx="69" lly="0" urx="378" ury="710"/> + <char name="onehalf" width="834" llx="26" lly="-19" urx="794" ury="710"/> + <char name="onequarter" width="834" llx="26" lly="-19" urx="766" ury="710"/> + <char name="onesuperior" width="333" llx="26" lly="283" urx="237" ury="710"/> + <char name="ordfeminine" width="370" llx="22" lly="401" urx="347" ury="737"/> + <char name="ordmasculine" width="365" llx="6" lly="401" urx="360" ury="737"/> + <char name="oslash" width="611" llx="22" lly="-29" urx="589" ury="560"/> + <char name="otilde" width="611" llx="34" lly="-14" urx="578" ury="737"/> + <char name="p" width="611" llx="62" lly="-207" urx="578" ury="546"/> + <char name="paragraph" width="556" llx="-8" lly="-191" urx="539" ury="700"/> + <char name="parenleft" width="333" llx="35" lly="-208" urx="314" ury="734"/> + <char name="parenright" width="333" llx="19" lly="-208" urx="298" ury="734"/> + <char name="percent" width="889" llx="28" lly="-19" urx="861" ury="710"/> + <char name="period" width="278" llx="64" lly="0" urx="214" ury="146"/> + <char name="periodcentered" width="278" llx="58" lly="172" urx="220" ury="334"/> + <char name="perthousand" width="1000" llx="-3" lly="-19" urx="1003" ury="710"/> + <char name="plus" width="584" llx="40" lly="0" urx="544" ury="506"/> + <char name="plusminus" width="584" llx="40" lly="0" urx="544" ury="506"/> + <char name="q" width="611" llx="34" lly="-207" urx="552" ury="546"/> + <char name="question" width="611" llx="60" lly="0" urx="556" ury="727"/> + <char name="questiondown" width="611" llx="55" lly="-195" urx="551" ury="532"/> + <char name="quotedbl" width="474" llx="98" lly="447" urx="376" ury="718"/> + <char name="quotedblbase" width="500" llx="64" lly="-146" urx="436" ury="127"/> + <char name="quotedblleft" width="500" llx="64" lly="454" urx="436" ury="727"/> + <char name="quotedblright" width="500" llx="64" lly="445" urx="436" ury="718"/> + <char name="quoteleft" width="278" llx="69" lly="454" urx="209" ury="727"/> + <char name="quoteright" width="278" llx="69" lly="445" urx="209" ury="718"/> + <char name="quotesinglbase" width="278" llx="69" lly="-146" urx="209" ury="127"/> + <char name="quotesingle" width="238" llx="70" lly="447" urx="168" ury="718"/> + <char name="r" width="389" llx="64" lly="0" urx="373" ury="546"/> + <char name="registered" width="737" llx="-11" lly="-19" urx="748" ury="737"/> + <char name="ring" width="333" llx="59" lly="568" urx="275" ury="776"/> + <char name="s" width="556" llx="30" lly="-14" urx="519" ury="546"/> + <char name="scaron" width="556" llx="30" lly="-14" urx="519" ury="750"/> + <char name="section" width="556" llx="34" lly="-184" urx="522" ury="727"/> + <char name="semicolon" width="333" llx="92" lly="-168" urx="242" ury="512"/> + <char name="seven" width="556" llx="25" lly="0" urx="528" ury="698"/> + <char name="six" width="556" llx="31" lly="-19" urx="520" ury="710"/> + <char name="slash" width="278" llx="-33" lly="-19" urx="311" ury="737"/> + <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="278"/> - <char name="sterling" width="556"/> - <char name="t" width="333"/> - <char name="thorn" width="611"/> - <char name="three" width="556"/> - <char name="threequarters" width="834"/> - <char name="threesuperior" width="333"/> - <char name="tilde" width="333"/> - <char name="trademark" width="1000"/> - <char name="two" width="556"/> - <char name="twosuperior" width="333"/> - <char name="u" width="611"/> - <char name="uacute" width="611"/> - <char name="ucircumflex" width="611"/> - <char name="udieresis" width="611"/> - <char name="ugrave" width="611"/> - <char name="underscore" width="556"/> - <char name="v" width="556"/> - <char name="w" width="778"/> - <char name="x" width="556"/> - <char name="y" width="556"/> - <char name="yacute" width="556"/> - <char name="ydieresis" width="556"/> - <char name="yen" width="556"/> - <char name="z" width="500"/> - <char name="zcaron" width="500"/> - <char name="zero" width="556"/> - </widths> + <char name="sterling" width="556" llx="28" lly="-16" urx="541" ury="718"/> + <char name="t" width="333" llx="10" lly="-6" urx="309" ury="676"/> + <char name="thorn" width="611" llx="62" lly="-208" urx="578" ury="718"/> + <char name="three" width="556" llx="27" lly="-19" urx="516" ury="710"/> + <char name="threequarters" width="834" llx="16" lly="-19" urx="799" ury="710"/> + <char name="threesuperior" width="333" llx="8" lly="271" urx="326" ury="710"/> + <char name="tilde" width="333" llx="-17" lly="610" urx="350" ury="737"/> + <char name="trademark" width="1000" llx="44" lly="306" urx="956" ury="718"/> + <char name="two" width="556" llx="26" lly="0" urx="511" ury="710"/> + <char name="twosuperior" width="333" llx="9" lly="283" urx="324" ury="710"/> + <char name="u" width="611" llx="66" lly="-14" urx="545" ury="532"/> + <char name="uacute" width="611" llx="66" lly="-14" urx="545" ury="750"/> + <char name="ucircumflex" width="611" llx="66" lly="-14" urx="545" ury="750"/> + <char name="udieresis" width="611" llx="66" lly="-14" urx="545" ury="729"/> + <char name="ugrave" width="611" llx="66" lly="-14" urx="545" ury="750"/> + <char name="underscore" width="556" llx="0" lly="-125" urx="556" ury="-75"/> + <char name="v" width="556" llx="13" lly="0" urx="543" ury="532"/> + <char name="w" width="778" llx="10" lly="0" urx="769" ury="532"/> + <char name="x" width="556" llx="15" lly="0" urx="541" ury="532"/> + <char name="y" width="556" llx="10" lly="-214" urx="539" ury="532"/> + <char name="yacute" width="556" llx="10" lly="-214" urx="539" ury="750"/> + <char name="ydieresis" width="556" llx="10" lly="-214" urx="539" ury="729"/> + <char name="yen" width="556" llx="-9" lly="0" urx="565" ury="698"/> + <char name="z" width="500" llx="20" lly="0" urx="480" ury="532"/> + <char name="zcaron" width="500" llx="20" lly="0" urx="480" ury="750"/> + <char name="zero" width="556" llx="32" lly="-19" urx="524" ury="710"/> + </char-metrics> <kerning kpx1="107"> <pair kern="-15" kpx2="111"/> </kerning> diff --git a/src/codegen/fonts/HelveticaBoldOblique.xml b/src/codegen/fonts/HelveticaBoldOblique.xml index c11e0ba18..e1d0fd294 100644 --- a/src/codegen/fonts/HelveticaBoldOblique.xml +++ b/src/codegen/fonts/HelveticaBoldOblique.xml @@ -22,245 +22,246 @@ <family-name>Helvetica</family-name> <class-name>HelveticaBoldOblique</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>718</cap-height> <x-height>532</x-height> <ascender>718</ascender> <descender>-207</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="722"/> - <char name="AE" width="1000"/> - <char name="Aacute" width="722"/> - <char name="Acircumflex" width="722"/> - <char name="Adieresis" width="722"/> - <char name="Agrave" width="722"/> - <char name="Aring" width="722"/> - <char name="Atilde" width="722"/> - <char name="B" width="722"/> - <char name="C" width="722"/> - <char name="Ccedilla" width="722"/> - <char name="D" width="722"/> - <char name="E" width="667"/> - <char name="Eacute" width="667"/> - <char name="Ecircumflex" width="667"/> - <char name="Edieresis" width="667"/> - <char name="Egrave" width="667"/> - <char name="Eth" width="722"/> - <char name="Euro" width="556"/> - <char name="F" width="611"/> - <char name="G" width="778"/> - <char name="H" width="722"/> - <char name="I" width="278"/> - <char name="Iacute" width="278"/> - <char name="Icircumflex" width="278"/> - <char name="Idieresis" width="278"/> - <char name="Igrave" width="278"/> - <char name="J" width="556"/> - <char name="K" width="722"/> - <char name="L" width="611"/> - <char name="Lslash" width="611"/> - <char name="M" width="833"/> - <char name="N" width="722"/> - <char name="Ntilde" width="722"/> - <char name="O" width="778"/> - <char name="OE" width="1000"/> - <char name="Oacute" width="778"/> - <char name="Ocircumflex" width="778"/> - <char name="Odieresis" width="778"/> - <char name="Ograve" width="778"/> - <char name="Oslash" width="778"/> - <char name="Otilde" width="778"/> - <char name="P" width="667"/> - <char name="Q" width="778"/> - <char name="R" width="722"/> - <char name="S" width="667"/> - <char name="Scaron" width="667"/> - <char name="T" width="611"/> - <char name="Thorn" width="667"/> - <char name="U" width="722"/> - <char name="Uacute" width="722"/> - <char name="Ucircumflex" width="722"/> - <char name="Udieresis" width="722"/> - <char name="Ugrave" width="722"/> - <char name="V" width="667"/> - <char name="W" width="944"/> - <char name="X" width="667"/> - <char name="Y" width="667"/> - <char name="Yacute" width="667"/> - <char name="Ydieresis" width="667"/> - <char name="Z" width="611"/> - <char name="Zcaron" width="611"/> - <char name="a" width="556"/> - <char name="aacute" width="556"/> - <char name="acircumflex" width="556"/> - <char name="acute" width="333"/> - <char name="adieresis" width="556"/> - <char name="ae" width="889"/> - <char name="agrave" width="556"/> - <char name="ampersand" width="722"/> - <char name="aring" width="556"/> - <char name="asciicircum" width="584"/> - <char name="asciitilde" width="584"/> - <char name="asterisk" width="389"/> - <char name="at" width="975"/> - <char name="atilde" width="556"/> - <char name="b" width="611"/> - <char name="backslash" width="278"/> - <char name="bar" width="280"/> - <char name="braceleft" width="389"/> - <char name="braceright" width="389"/> - <char name="bracketleft" width="333"/> - <char name="bracketright" width="333"/> - <char name="breve" width="333"/> - <char name="brokenbar" width="280"/> - <char name="bullet" width="350"/> - <char name="c" width="556"/> - <char name="caron" width="333"/> - <char name="ccedilla" width="556"/> - <char name="cedilla" width="333"/> - <char name="cent" width="556"/> - <char name="circumflex" width="333"/> - <char name="colon" width="333"/> - <char name="comma" width="278"/> - <char name="copyright" width="737"/> - <char name="currency" width="556"/> - <char name="d" width="611"/> - <char name="dagger" width="556"/> - <char name="daggerdbl" width="556"/> - <char name="degree" width="400"/> - <char name="dieresis" width="333"/> - <char name="divide" width="584"/> - <char name="dollar" width="556"/> - <char name="dotaccent" width="333"/> - <char name="dotlessi" width="278"/> - <char name="e" width="556"/> - <char name="eacute" width="556"/> - <char name="ecircumflex" width="556"/> - <char name="edieresis" width="556"/> - <char name="egrave" width="556"/> - <char name="eight" width="556"/> - <char name="ellipsis" width="1000"/> - <char name="emdash" width="1000"/> - <char name="endash" width="556"/> - <char name="equal" width="584"/> - <char name="eth" width="611"/> - <char name="exclam" width="333"/> - <char name="exclamdown" width="333"/> - <char name="f" width="333"/> - <char name="fi" width="611"/> - <char name="five" width="556"/> - <char name="fl" width="611"/> - <char name="florin" width="556"/> - <char name="four" width="556"/> - <char name="fraction" width="167"/> - <char name="g" width="611"/> - <char name="germandbls" width="611"/> - <char name="grave" width="333"/> - <char name="greater" width="584"/> - <char name="guillemotleft" width="556"/> - <char name="guillemotright" width="556"/> - <char name="guilsinglleft" width="333"/> - <char name="guilsinglright" width="333"/> - <char name="h" width="611"/> - <char name="hungarumlaut" width="333"/> - <char name="hyphen" width="333"/> - <char name="i" width="278"/> - <char name="iacute" width="278"/> - <char name="icircumflex" width="278"/> - <char name="idieresis" width="278"/> - <char name="igrave" width="278"/> - <char name="j" width="278"/> - <char name="k" width="556"/> - <char name="l" width="278"/> - <char name="less" width="584"/> - <char name="logicalnot" width="584"/> - <char name="lslash" width="278"/> - <char name="m" width="889"/> - <char name="macron" width="333"/> - <char name="minus" width="324"/> - <char name="mu" width="611"/> - <char name="multiply" width="584"/> - <char name="n" width="611"/> - <char name="nine" width="556"/> - <char name="ntilde" width="611"/> - <char name="numbersign" width="556"/> - <char name="o" width="611"/> - <char name="oacute" width="611"/> - <char name="ocircumflex" width="611"/> - <char name="odieresis" width="611"/> - <char name="oe" width="944"/> - <char name="ogonek" width="333"/> - <char name="ograve" width="611"/> - <char name="one" width="556"/> - <char name="onehalf" width="834"/> - <char name="onequarter" width="834"/> - <char name="onesuperior" width="333"/> - <char name="ordfeminine" width="370"/> - <char name="ordmasculine" width="365"/> - <char name="oslash" width="611"/> - <char name="otilde" width="611"/> - <char name="p" width="611"/> - <char name="paragraph" width="556"/> - <char name="parenleft" width="333"/> - <char name="parenright" width="333"/> - <char name="percent" width="889"/> - <char name="period" width="278"/> - <char name="periodcentered" width="278"/> - <char name="perthousand" width="1000"/> - <char name="plus" width="584"/> - <char name="plusminus" width="584"/> - <char name="q" width="611"/> - <char name="question" width="611"/> - <char name="questiondown" width="611"/> - <char name="quotedbl" width="474"/> - <char name="quotedblbase" width="500"/> - <char name="quotedblleft" width="500"/> - <char name="quotedblright" width="500"/> - <char name="quoteleft" width="278"/> - <char name="quoteright" width="278"/> - <char name="quotesinglbase" width="278"/> - <char name="quotesingle" width="238"/> - <char name="r" width="389"/> - <char name="registered" width="737"/> - <char name="ring" width="333"/> - <char name="s" width="556"/> - <char name="scaron" width="556"/> - <char name="section" width="556"/> - <char name="semicolon" width="333"/> - <char name="seven" width="556"/> - <char name="six" width="556"/> - <char name="slash" width="278"/> - <char name="space" width="278"/> + <char-metrics> + <char name="A" width="722" llx="20" lly="0" urx="702" ury="718"/> + <char name="AE" width="1000" llx="5" lly="0" urx="1100" ury="718"/> + <char name="Aacute" width="722" llx="20" lly="0" urx="750" ury="936"/> + <char name="Acircumflex" width="722" llx="20" lly="0" urx="706" ury="936"/> + <char name="Adieresis" width="722" llx="20" lly="0" urx="716" ury="915"/> + <char name="Agrave" width="722" llx="20" lly="0" urx="702" ury="936"/> + <char name="Aring" width="722" llx="20" lly="0" urx="702" ury="962"/> + <char name="Atilde" width="722" llx="20" lly="0" urx="741" ury="923"/> + <char name="B" width="722" llx="76" lly="0" urx="764" ury="718"/> + <char name="C" width="722" llx="107" lly="-19" urx="789" ury="737"/> + <char name="Ccedilla" width="722" llx="107" lly="-228" urx="789" ury="737"/> + <char name="D" width="722" llx="76" lly="0" urx="777" ury="718"/> + <char name="E" width="667" llx="76" lly="0" urx="757" ury="718"/> + <char name="Eacute" width="667" llx="76" lly="0" urx="757" ury="936"/> + <char name="Ecircumflex" width="667" llx="76" lly="0" urx="757" ury="936"/> + <char name="Edieresis" width="667" llx="76" lly="0" urx="757" ury="915"/> + <char name="Egrave" width="667" llx="76" lly="0" urx="757" ury="936"/> + <char name="Eth" width="722" llx="62" lly="0" urx="777" ury="718"/> + <char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="611" llx="76" lly="0" urx="740" ury="718"/> + <char name="G" width="778" llx="108" lly="-19" urx="817" ury="737"/> + <char name="H" width="722" llx="71" lly="0" urx="804" ury="718"/> + <char name="I" width="278" llx="64" lly="0" urx="367" ury="718"/> + <char name="Iacute" width="278" llx="64" lly="0" urx="528" ury="936"/> + <char name="Icircumflex" width="278" llx="64" lly="0" urx="484" ury="936"/> + <char name="Idieresis" width="278" llx="64" lly="0" urx="494" ury="915"/> + <char name="Igrave" width="278" llx="64" lly="0" urx="367" ury="936"/> + <char name="J" width="556" llx="60" lly="-18" urx="637" ury="718"/> + <char name="K" width="722" llx="87" lly="0" urx="858" ury="718"/> + <char name="L" width="611" llx="76" lly="0" urx="611" ury="718"/> + <char name="Lslash" width="611" llx="34" lly="0" urx="611" ury="718"/> + <char name="M" width="833" llx="69" lly="0" urx="918" ury="718"/> + <char name="N" width="722" llx="69" lly="0" urx="807" ury="718"/> + <char name="Ntilde" width="722" llx="69" lly="0" urx="807" ury="923"/> + <char name="O" width="778" llx="107" lly="-19" urx="823" ury="737"/> + <char name="OE" width="1000" llx="99" lly="-19" urx="1114" ury="737"/> + <char name="Oacute" width="778" llx="107" lly="-19" urx="823" ury="936"/> + <char name="Ocircumflex" width="778" llx="107" lly="-19" urx="823" ury="936"/> + <char name="Odieresis" width="778" llx="107" lly="-19" urx="823" ury="915"/> + <char name="Ograve" width="778" llx="107" lly="-19" urx="823" ury="936"/> + <char name="Oslash" width="778" llx="35" lly="-27" urx="894" ury="745"/> + <char name="Otilde" width="778" llx="107" lly="-19" urx="823" ury="923"/> + <char name="P" width="667" llx="76" lly="0" urx="738" ury="718"/> + <char name="Q" width="778" llx="107" lly="-52" urx="823" ury="737"/> + <char name="R" width="722" llx="76" lly="0" urx="778" ury="718"/> + <char name="S" width="667" llx="81" lly="-19" urx="718" ury="737"/> + <char name="Scaron" width="667" llx="81" lly="-19" urx="718" ury="936"/> + <char name="T" width="611" llx="140" lly="0" urx="751" ury="718"/> + <char name="Thorn" width="667" llx="76" lly="0" urx="716" ury="718"/> + <char name="U" width="722" llx="116" lly="-19" urx="804" ury="718"/> + <char name="Uacute" width="722" llx="116" lly="-19" urx="804" ury="936"/> + <char name="Ucircumflex" width="722" llx="116" lly="-19" urx="804" ury="936"/> + <char name="Udieresis" width="722" llx="116" lly="-19" urx="804" ury="915"/> + <char name="Ugrave" width="722" llx="116" lly="-19" urx="804" ury="936"/> + <char name="V" width="667" llx="172" lly="0" urx="801" ury="718"/> + <char name="W" width="944" llx="169" lly="0" urx="1082" ury="718"/> + <char name="X" width="667" llx="14" lly="0" urx="791" ury="718"/> + <char name="Y" width="667" llx="168" lly="0" urx="806" ury="718"/> + <char name="Yacute" width="667" llx="168" lly="0" urx="806" ury="936"/> + <char name="Ydieresis" width="667" llx="168" lly="0" urx="806" ury="915"/> + <char name="Z" width="611" llx="25" lly="0" urx="737" ury="718"/> + <char name="Zcaron" width="611" llx="25" lly="0" urx="737" ury="936"/> + <char name="a" width="556" llx="55" lly="-14" urx="583" ury="546"/> + <char name="aacute" width="556" llx="55" lly="-14" urx="627" ury="750"/> + <char name="acircumflex" width="556" llx="55" lly="-14" urx="583" ury="750"/> + <char name="acute" width="333" llx="236" lly="604" urx="515" ury="750"/> + <char name="adieresis" width="556" llx="55" lly="-14" urx="594" ury="729"/> + <char name="ae" width="889" llx="56" lly="-14" urx="923" ury="546"/> + <char name="agrave" width="556" llx="55" lly="-14" urx="583" ury="750"/> + <char name="ampersand" width="722" llx="89" lly="-19" urx="732" ury="718"/> + <char name="aring" width="556" llx="55" lly="-14" urx="583" ury="776"/> + <char name="asciicircum" width="584" llx="131" lly="323" urx="591" ury="698"/> + <char name="asciitilde" width="584" llx="115" lly="163" urx="577" ury="343"/> + <char name="asterisk" width="389" llx="146" lly="387" urx="481" ury="718"/> + <char name="at" width="975" llx="186" lly="-19" urx="954" ury="737"/> + <char name="atilde" width="556" llx="55" lly="-14" urx="619" ury="737"/> + <char name="b" width="611" llx="61" lly="-14" urx="645" ury="718"/> + <char name="backslash" width="278" llx="124" lly="-19" urx="307" ury="737"/> + <char name="bar" width="280" llx="36" lly="-225" urx="361" ury="775"/> + <char name="braceleft" width="389" llx="94" lly="-196" urx="518" ury="722"/> + <char name="braceright" width="389" llx="-18" lly="-196" urx="407" ury="722"/> + <char name="bracketleft" width="333" llx="21" lly="-196" urx="462" ury="722"/> + <char name="bracketright" width="333" llx="-18" lly="-196" urx="423" ury="722"/> + <char name="breve" width="333" llx="156" lly="604" urx="494" ury="750"/> + <char name="brokenbar" width="280" llx="52" lly="-150" urx="345" ury="700"/> + <char name="bullet" width="350" llx="83" lly="194" urx="420" ury="524"/> + <char name="c" width="556" llx="79" lly="-14" urx="599" ury="546"/> + <char name="caron" width="333" llx="149" lly="604" urx="502" ury="750"/> + <char name="ccedilla" width="556" llx="79" lly="-228" urx="599" ury="546"/> + <char name="cedilla" width="333" llx="-37" lly="-228" urx="220" ury="0"/> + <char name="cent" width="556" llx="79" lly="-118" urx="599" ury="628"/> + <char name="circumflex" width="333" llx="118" lly="604" urx="471" ury="750"/> + <char name="colon" width="333" llx="92" lly="0" urx="351" ury="512"/> + <char name="comma" width="278" llx="28" lly="-168" urx="245" ury="146"/> + <char name="copyright" width="737" llx="56" lly="-19" urx="835" ury="737"/> + <char name="currency" width="556" llx="27" lly="76" urx="680" ury="636"/> + <char name="d" width="611" llx="82" lly="-14" urx="704" ury="718"/> + <char name="dagger" width="556" llx="118" lly="-171" urx="626" ury="718"/> + <char name="daggerdbl" width="556" llx="46" lly="-171" urx="628" ury="718"/> + <char name="degree" width="400" llx="175" lly="426" urx="467" ury="712"/> + <char name="dieresis" width="333" llx="137" lly="614" urx="482" ury="729"/> + <char name="divide" width="584" llx="82" lly="-42" urx="610" ury="548"/> + <char name="dollar" width="556" llx="67" lly="-115" urx="622" ury="775"/> + <char name="dotaccent" width="333" llx="235" lly="614" urx="385" ury="729"/> + <char name="dotlessi" width="278" llx="69" lly="0" urx="322" ury="532"/> + <char name="e" width="556" llx="70" lly="-14" urx="593" ury="546"/> + <char name="eacute" width="556" llx="70" lly="-14" urx="627" ury="750"/> + <char name="ecircumflex" width="556" llx="70" lly="-14" urx="593" ury="750"/> + <char name="edieresis" width="556" llx="70" lly="-14" urx="594" ury="729"/> + <char name="egrave" width="556" llx="70" lly="-14" urx="593" ury="750"/> + <char name="eight" width="556" llx="69" lly="-19" urx="616" ury="710"/> + <char name="ellipsis" width="1000" llx="92" lly="0" urx="939" ury="146"/> + <char name="emdash" width="1000" llx="48" lly="227" urx="1071" ury="333"/> + <char name="endash" width="556" llx="48" lly="227" urx="627" ury="333"/> + <char name="equal" width="584" llx="58" lly="87" urx="633" ury="419"/> + <char name="eth" width="611" llx="82" lly="-14" urx="670" ury="737"/> + <char name="exclam" width="333" llx="94" lly="0" urx="397" ury="718"/> + <char name="exclamdown" width="333" llx="50" lly="-186" urx="353" ury="532"/> + <char name="f" width="333" llx="87" lly="0" urx="469" ury="727"/> + <char name="fi" width="611" llx="87" lly="0" urx="696" ury="727"/> + <char name="five" width="556" llx="64" lly="-19" urx="636" ury="698"/> + <char name="fl" width="611" llx="87" lly="0" urx="695" ury="727"/> + <char name="florin" width="556" llx="-50" lly="-210" urx="669" ury="737"/> + <char name="four" width="556" llx="60" lly="0" urx="598" ury="710"/> + <char name="fraction" width="167" llx="-174" lly="-19" urx="487" ury="710"/> + <char name="g" width="611" llx="38" lly="-217" urx="666" ury="546"/> + <char name="germandbls" width="611" llx="69" lly="-14" urx="657" ury="731"/> + <char name="grave" width="333" llx="136" lly="604" urx="353" ury="750"/> + <char name="greater" width="584" llx="36" lly="-8" urx="609" ury="514"/> + <char name="guillemotleft" width="556" llx="135" lly="76" urx="571" ury="484"/> + <char name="guillemotright" width="556" llx="104" lly="76" urx="540" ury="484"/> + <char name="guilsinglleft" width="333" llx="130" lly="76" urx="353" ury="484"/> + <char name="guilsinglright" width="333" llx="99" lly="76" urx="322" ury="484"/> + <char name="h" width="611" llx="65" lly="0" urx="629" ury="718"/> + <char name="hungarumlaut" width="333" llx="137" lly="604" urx="645" ury="750"/> + <char name="hyphen" width="333" llx="73" lly="215" urx="379" ury="345"/> + <char name="i" width="278" llx="69" lly="0" urx="363" ury="725"/> + <char name="iacute" width="278" llx="69" lly="0" urx="488" ury="750"/> + <char name="icircumflex" width="278" llx="69" lly="0" urx="444" ury="750"/> + <char name="idieresis" width="278" llx="69" lly="0" urx="455" ury="729"/> + <char name="igrave" width="278" llx="69" lly="0" urx="326" ury="750"/> + <char name="j" width="278" llx="-42" lly="-214" urx="363" ury="725"/> + <char name="k" width="556" llx="69" lly="0" urx="670" ury="718"/> + <char name="l" width="278" llx="69" lly="0" urx="362" ury="718"/> + <char name="less" width="584" llx="82" lly="-8" urx="655" ury="514"/> + <char name="logicalnot" width="584" llx="105" lly="108" urx="633" ury="419"/> + <char name="lslash" width="278" llx="40" lly="0" urx="407" ury="718"/> + <char name="m" width="889" llx="64" lly="0" urx="909" ury="546"/> + <char name="macron" width="333" llx="122" lly="604" urx="483" ury="678"/> + <char name="minus" width="324" llx="82" lly="197" urx="610" ury="309"/> + <char name="mu" width="611" llx="22" lly="-207" urx="658" ury="532"/> + <char name="multiply" width="584" llx="57" lly="1" urx="635" ury="505"/> + <char name="n" width="611" llx="65" lly="0" urx="629" ury="546"/> + <char name="nine" width="556" llx="78" lly="-19" urx="615" ury="710"/> + <char name="ntilde" width="611" llx="65" lly="0" urx="646" ury="737"/> + <char name="numbersign" width="556" llx="60" lly="0" urx="644" ury="698"/> + <char name="o" width="611" llx="82" lly="-14" urx="643" ury="546"/> + <char name="oacute" width="611" llx="82" lly="-14" urx="654" ury="750"/> + <char name="ocircumflex" width="611" llx="82" lly="-14" urx="643" ury="750"/> + <char name="odieresis" width="611" llx="82" lly="-14" urx="643" ury="729"/> + <char name="oe" width="944" llx="82" lly="-14" urx="977" ury="546"/> + <char name="ogonek" width="333" llx="41" lly="-228" urx="264" ury="0"/> + <char name="ograve" width="611" llx="82" lly="-14" urx="643" ury="750"/> + <char name="one" width="556" llx="173" lly="0" urx="529" ury="710"/> + <char name="onehalf" width="834" llx="132" lly="-19" urx="858" ury="710"/> + <char name="onequarter" width="834" llx="132" lly="-19" urx="806" ury="710"/> + <char name="onesuperior" width="333" llx="148" lly="283" urx="388" ury="710"/> + <char name="ordfeminine" width="370" llx="125" lly="401" urx="465" ury="737"/> + <char name="ordmasculine" width="365" llx="123" lly="401" urx="485" ury="737"/> + <char name="oslash" width="611" llx="22" lly="-29" urx="701" ury="560"/> + <char name="otilde" width="611" llx="82" lly="-14" urx="646" ury="737"/> + <char name="p" width="611" llx="18" lly="-207" urx="645" ury="546"/> + <char name="paragraph" width="556" llx="98" lly="-191" urx="688" ury="700"/> + <char name="parenleft" width="333" llx="76" lly="-208" urx="470" ury="734"/> + <char name="parenright" width="333" llx="-25" lly="-208" urx="369" ury="734"/> + <char name="percent" width="889" llx="136" lly="-19" urx="901" ury="710"/> + <char name="period" width="278" llx="64" lly="0" urx="245" ury="146"/> + <char name="periodcentered" width="278" llx="110" lly="172" urx="276" ury="334"/> + <char name="perthousand" width="1000" llx="76" lly="-19" urx="1038" ury="710"/> + <char name="plus" width="584" llx="82" lly="0" urx="610" ury="506"/> + <char name="plusminus" width="584" llx="40" lly="0" urx="625" ury="506"/> + <char name="q" width="611" llx="80" lly="-207" urx="665" ury="546"/> + <char name="question" width="611" llx="165" lly="0" urx="671" ury="727"/> + <char name="questiondown" width="611" llx="53" lly="-195" urx="559" ury="532"/> + <char name="quotedbl" width="474" llx="193" lly="447" urx="529" ury="718"/> + <char name="quotedblbase" width="500" llx="36" lly="-146" urx="463" ury="127"/> + <char name="quotedblleft" width="500" llx="160" lly="454" urx="588" ury="727"/> + <char name="quotedblright" width="500" llx="162" lly="445" urx="589" ury="718"/> + <char name="quoteleft" width="278" llx="165" lly="454" urx="361" ury="727"/> + <char name="quoteright" width="278" llx="167" lly="445" urx="362" ury="718"/> + <char name="quotesinglbase" width="278" llx="41" lly="-146" urx="236" ury="127"/> + <char name="quotesingle" width="238" llx="165" lly="447" urx="321" ury="718"/> + <char name="r" width="389" llx="64" lly="0" urx="489" ury="546"/> + <char name="registered" width="737" llx="55" lly="-19" urx="834" ury="737"/> + <char name="ring" width="333" llx="200" lly="568" urx="420" ury="776"/> + <char name="s" width="556" llx="63" lly="-14" urx="584" ury="546"/> + <char name="scaron" width="556" llx="63" lly="-14" urx="614" ury="750"/> + <char name="section" width="556" llx="61" lly="-184" urx="598" ury="727"/> + <char name="semicolon" width="333" llx="56" lly="-168" urx="351" ury="512"/> + <char name="seven" width="556" llx="125" lly="0" urx="676" ury="698"/> + <char name="six" width="556" llx="85" lly="-19" urx="619" ury="710"/> + <char name="slash" width="278" llx="-37" lly="-19" urx="468" ury="737"/> + <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="278"/> - <char name="sterling" width="556"/> - <char name="t" width="333"/> - <char name="thorn" width="611"/> - <char name="three" width="556"/> - <char name="threequarters" width="834"/> - <char name="threesuperior" width="333"/> - <char name="tilde" width="333"/> - <char name="trademark" width="1000"/> - <char name="two" width="556"/> - <char name="twosuperior" width="333"/> - <char name="u" width="611"/> - <char name="uacute" width="611"/> - <char name="ucircumflex" width="611"/> - <char name="udieresis" width="611"/> - <char name="ugrave" width="611"/> - <char name="underscore" width="556"/> - <char name="v" width="556"/> - <char name="w" width="778"/> - <char name="x" width="556"/> - <char name="y" width="556"/> - <char name="yacute" width="556"/> - <char name="ydieresis" width="556"/> - <char name="yen" width="556"/> - <char name="z" width="500"/> - <char name="zcaron" width="500"/> - <char name="zero" width="556"/> - </widths> + <char name="sterling" width="556" llx="50" lly="-16" urx="635" ury="718"/> + <char name="t" width="333" llx="100" lly="-6" urx="422" ury="676"/> + <char name="thorn" width="611" llx="18" lly="-208" urx="645" ury="718"/> + <char name="three" width="556" llx="65" lly="-19" urx="608" ury="710"/> + <char name="threequarters" width="834" llx="99" lly="-19" urx="839" ury="710"/> + <char name="threesuperior" width="333" llx="91" lly="271" urx="441" ury="710"/> + <char name="tilde" width="333" llx="113" lly="610" urx="507" ury="737"/> + <char name="trademark" width="1000" llx="179" lly="306" urx="1109" ury="718"/> + <char name="two" width="556" llx="26" lly="0" urx="619" ury="710"/> + <char name="twosuperior" width="333" llx="69" lly="283" urx="449" ury="710"/> + <char name="u" width="611" llx="98" lly="-14" urx="658" ury="532"/> + <char name="uacute" width="611" llx="98" lly="-14" urx="658" ury="750"/> + <char name="ucircumflex" width="611" llx="98" lly="-14" urx="658" ury="750"/> + <char name="udieresis" width="611" llx="98" lly="-14" urx="658" ury="729"/> + <char name="ugrave" width="611" llx="98" lly="-14" urx="658" ury="750"/> + <char name="underscore" width="556" llx="-27" lly="-125" urx="540" ury="-75"/> + <char name="v" width="556" llx="126" lly="0" urx="656" ury="532"/> + <char name="w" width="778" llx="123" lly="0" urx="882" ury="532"/> + <char name="x" width="556" llx="15" lly="0" urx="648" ury="532"/> + <char name="y" width="556" llx="42" lly="-214" urx="652" ury="532"/> + <char name="yacute" width="556" llx="42" lly="-214" urx="652" ury="750"/> + <char name="ydieresis" width="556" llx="42" lly="-214" urx="652" ury="729"/> + <char name="yen" width="556" llx="60" lly="0" urx="713" ury="698"/> + <char name="z" width="500" llx="20" lly="0" urx="583" ury="532"/> + <char name="zcaron" width="500" llx="20" lly="0" urx="586" ury="750"/> + <char name="zero" width="556" llx="86" lly="-19" urx="617" ury="710"/> + </char-metrics> <kerning kpx1="107"> <pair kern="-15" kpx2="111"/> </kerning> diff --git a/src/codegen/fonts/HelveticaOblique.xml b/src/codegen/fonts/HelveticaOblique.xml index 7f651a5d9..efa1165f2 100644 --- a/src/codegen/fonts/HelveticaOblique.xml +++ b/src/codegen/fonts/HelveticaOblique.xml @@ -22,245 +22,246 @@ <family-name>Helvetica</family-name> <class-name>HelveticaOblique</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>718</cap-height> <x-height>523</x-height> <ascender>718</ascender> <descender>-207</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="667"/> - <char name="AE" width="1000"/> - <char name="Aacute" width="667"/> - <char name="Acircumflex" width="667"/> - <char name="Adieresis" width="667"/> - <char name="Agrave" width="667"/> - <char name="Aring" width="667"/> - <char name="Atilde" width="667"/> - <char name="B" width="667"/> - <char name="C" width="722"/> - <char name="Ccedilla" width="722"/> - <char name="D" width="722"/> - <char name="E" width="667"/> - <char name="Eacute" width="667"/> - <char name="Ecircumflex" width="667"/> - <char name="Edieresis" width="667"/> - <char name="Egrave" width="667"/> - <char name="Eth" width="722"/> - <char name="Euro" width="556"/> - <char name="F" width="611"/> - <char name="G" width="778"/> - <char name="H" width="722"/> - <char name="I" width="278"/> - <char name="Iacute" width="278"/> - <char name="Icircumflex" width="278"/> - <char name="Idieresis" width="278"/> - <char name="Igrave" width="278"/> - <char name="J" width="500"/> - <char name="K" width="667"/> - <char name="L" width="556"/> - <char name="Lslash" width="556"/> - <char name="M" width="833"/> - <char name="N" width="722"/> - <char name="Ntilde" width="722"/> - <char name="O" width="778"/> - <char name="OE" width="1000"/> - <char name="Oacute" width="778"/> - <char name="Ocircumflex" width="778"/> - <char name="Odieresis" width="778"/> - <char name="Ograve" width="778"/> - <char name="Oslash" width="778"/> - <char name="Otilde" width="778"/> - <char name="P" width="667"/> - <char name="Q" width="778"/> - <char name="R" width="722"/> - <char name="S" width="667"/> - <char name="Scaron" width="667"/> - <char name="T" width="611"/> - <char name="Thorn" width="667"/> - <char name="U" width="722"/> - <char name="Uacute" width="722"/> - <char name="Ucircumflex" width="722"/> - <char name="Udieresis" width="722"/> - <char name="Ugrave" width="722"/> - <char name="V" width="667"/> - <char name="W" width="944"/> - <char name="X" width="667"/> - <char name="Y" width="667"/> - <char name="Yacute" width="667"/> - <char name="Ydieresis" width="667"/> - <char name="Z" width="611"/> - <char name="Zcaron" width="611"/> - <char name="a" width="556"/> - <char name="aacute" width="556"/> - <char name="acircumflex" width="556"/> - <char name="acute" width="333"/> - <char name="adieresis" width="556"/> - <char name="ae" width="889"/> - <char name="agrave" width="556"/> - <char name="ampersand" width="667"/> - <char name="aring" width="556"/> - <char name="asciicircum" width="469"/> - <char name="asciitilde" width="584"/> - <char name="asterisk" width="389"/> - <char name="at" width="1015"/> - <char name="atilde" width="556"/> - <char name="b" width="556"/> - <char name="backslash" width="278"/> - <char name="bar" width="260"/> - <char name="braceleft" width="334"/> - <char name="braceright" width="334"/> - <char name="bracketleft" width="278"/> - <char name="bracketright" width="278"/> - <char name="breve" width="333"/> - <char name="brokenbar" width="260"/> - <char name="bullet" width="350"/> - <char name="c" width="500"/> - <char name="caron" width="333"/> - <char name="ccedilla" width="500"/> - <char name="cedilla" width="333"/> - <char name="cent" width="556"/> - <char name="circumflex" width="333"/> - <char name="colon" width="278"/> - <char name="comma" width="278"/> - <char name="copyright" width="737"/> - <char name="currency" width="556"/> - <char name="d" width="556"/> - <char name="dagger" width="556"/> - <char name="daggerdbl" width="556"/> - <char name="degree" width="400"/> - <char name="dieresis" width="333"/> - <char name="divide" width="584"/> - <char name="dollar" width="556"/> - <char name="dotaccent" width="333"/> - <char name="dotlessi" width="278"/> - <char name="e" width="556"/> - <char name="eacute" width="556"/> - <char name="ecircumflex" width="556"/> - <char name="edieresis" width="556"/> - <char name="egrave" width="556"/> - <char name="eight" width="556"/> - <char name="ellipsis" width="1000"/> - <char name="emdash" width="1000"/> - <char name="endash" width="556"/> - <char name="equal" width="584"/> - <char name="eth" width="556"/> - <char name="exclam" width="278"/> - <char name="exclamdown" width="333"/> - <char name="f" width="278"/> - <char name="fi" width="500"/> - <char name="five" width="556"/> - <char name="fl" width="500"/> - <char name="florin" width="556"/> - <char name="four" width="556"/> - <char name="fraction" width="167"/> - <char name="g" width="556"/> - <char name="germandbls" width="611"/> - <char name="grave" width="333"/> - <char name="greater" width="584"/> - <char name="guillemotleft" width="556"/> - <char name="guillemotright" width="556"/> - <char name="guilsinglleft" width="333"/> - <char name="guilsinglright" width="333"/> - <char name="h" width="556"/> - <char name="hungarumlaut" width="333"/> - <char name="hyphen" width="333"/> - <char name="i" width="222"/> - <char name="iacute" width="278"/> - <char name="icircumflex" width="278"/> - <char name="idieresis" width="278"/> - <char name="igrave" width="278"/> - <char name="j" width="222"/> - <char name="k" width="500"/> - <char name="l" width="222"/> - <char name="less" width="584"/> - <char name="logicalnot" width="584"/> - <char name="lslash" width="222"/> - <char name="m" width="833"/> - <char name="macron" width="333"/> - <char name="minus" width="584"/> - <char name="mu" width="556"/> - <char name="multiply" width="584"/> - <char name="n" width="556"/> - <char name="nine" width="556"/> - <char name="ntilde" width="556"/> - <char name="numbersign" width="556"/> - <char name="o" width="556"/> - <char name="oacute" width="556"/> - <char name="ocircumflex" width="556"/> - <char name="odieresis" width="556"/> - <char name="oe" width="944"/> - <char name="ogonek" width="333"/> - <char name="ograve" width="556"/> - <char name="one" width="556"/> - <char name="onehalf" width="834"/> - <char name="onequarter" width="834"/> - <char name="onesuperior" width="333"/> - <char name="ordfeminine" width="370"/> - <char name="ordmasculine" width="365"/> - <char name="oslash" width="611"/> - <char name="otilde" width="556"/> - <char name="p" width="556"/> - <char name="paragraph" width="537"/> - <char name="parenleft" width="333"/> - <char name="parenright" width="333"/> - <char name="percent" width="889"/> - <char name="period" width="278"/> - <char name="periodcentered" width="278"/> - <char name="perthousand" width="1000"/> - <char name="plus" width="584"/> - <char name="plusminus" width="584"/> - <char name="q" width="556"/> - <char name="question" width="556"/> - <char name="questiondown" width="611"/> - <char name="quotedbl" width="355"/> - <char name="quotedblbase" width="333"/> - <char name="quotedblleft" width="333"/> - <char name="quotedblright" width="333"/> - <char name="quoteleft" width="222"/> - <char name="quoteright" width="222"/> - <char name="quotesinglbase" width="222"/> - <char name="quotesingle" width="191"/> - <char name="r" width="333"/> - <char name="registered" width="737"/> - <char name="ring" width="333"/> - <char name="s" width="500"/> - <char name="scaron" width="500"/> - <char name="section" width="556"/> - <char name="semicolon" width="278"/> - <char name="seven" width="556"/> - <char name="six" width="556"/> - <char name="slash" width="278"/> - <char name="space" width="278"/> + <char-metrics> + <char name="A" width="667" llx="14" lly="0" urx="654" ury="718"/> + <char name="AE" width="1000" llx="8" lly="0" urx="1097" ury="718"/> + <char name="Aacute" width="667" llx="14" lly="0" urx="683" ury="929"/> + <char name="Acircumflex" width="667" llx="14" lly="0" urx="654" ury="929"/> + <char name="Adieresis" width="667" llx="14" lly="0" urx="654" ury="901"/> + <char name="Agrave" width="667" llx="14" lly="0" urx="654" ury="929"/> + <char name="Aring" width="667" llx="14" lly="0" urx="654" ury="931"/> + <char name="Atilde" width="667" llx="14" lly="0" urx="699" ury="917"/> + <char name="B" width="667" llx="74" lly="0" urx="712" ury="718"/> + <char name="C" width="722" llx="108" lly="-19" urx="782" ury="737"/> + <char name="Ccedilla" width="722" llx="108" lly="-225" urx="782" ury="737"/> + <char name="D" width="722" llx="81" lly="0" urx="764" ury="718"/> + <char name="E" width="667" llx="86" lly="0" urx="762" ury="718"/> + <char name="Eacute" width="667" llx="86" lly="0" urx="762" ury="929"/> + <char name="Ecircumflex" width="667" llx="86" lly="0" urx="762" ury="929"/> + <char name="Edieresis" width="667" llx="86" lly="0" urx="762" ury="901"/> + <char name="Egrave" width="667" llx="86" lly="0" urx="762" ury="929"/> + <char name="Eth" width="722" llx="69" lly="0" urx="764" ury="718"/> + <char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="611" llx="86" lly="0" urx="736" ury="718"/> + <char name="G" width="778" llx="111" lly="-19" urx="799" ury="737"/> + <char name="H" width="722" llx="77" lly="0" urx="799" ury="718"/> + <char name="I" width="278" llx="91" lly="0" urx="341" ury="718"/> + <char name="Iacute" width="278" llx="91" lly="0" urx="489" ury="929"/> + <char name="Icircumflex" width="278" llx="91" lly="0" urx="452" ury="929"/> + <char name="Idieresis" width="278" llx="91" lly="0" urx="458" ury="901"/> + <char name="Igrave" width="278" llx="91" lly="0" urx="351" ury="929"/> + <char name="J" width="500" llx="47" lly="-19" urx="581" ury="718"/> + <char name="K" width="667" llx="76" lly="0" urx="808" ury="718"/> + <char name="L" width="556" llx="76" lly="0" urx="555" ury="718"/> + <char name="Lslash" width="556" llx="41" lly="0" urx="555" ury="718"/> + <char name="M" width="833" llx="73" lly="0" urx="914" ury="718"/> + <char name="N" width="722" llx="76" lly="0" urx="799" ury="718"/> + <char name="Ntilde" width="722" llx="76" lly="0" urx="799" ury="917"/> + <char name="O" width="778" llx="105" lly="-19" urx="826" ury="737"/> + <char name="OE" width="1000" llx="98" lly="-19" urx="1116" ury="737"/> + <char name="Oacute" width="778" llx="105" lly="-19" urx="826" ury="929"/> + <char name="Ocircumflex" width="778" llx="105" lly="-19" urx="826" ury="929"/> + <char name="Odieresis" width="778" llx="105" lly="-19" urx="826" ury="901"/> + <char name="Ograve" width="778" llx="105" lly="-19" urx="826" ury="929"/> + <char name="Oslash" width="778" llx="43" lly="-19" urx="890" ury="737"/> + <char name="Otilde" width="778" llx="105" lly="-19" urx="826" ury="917"/> + <char name="P" width="667" llx="86" lly="0" urx="737" ury="718"/> + <char name="Q" width="778" llx="105" lly="-56" urx="826" ury="737"/> + <char name="R" width="722" llx="88" lly="0" urx="773" ury="718"/> + <char name="S" width="667" llx="90" lly="-19" urx="713" ury="737"/> + <char name="Scaron" width="667" llx="90" lly="-19" urx="713" ury="929"/> + <char name="T" width="611" llx="148" lly="0" urx="750" ury="718"/> + <char name="Thorn" width="667" llx="86" lly="0" urx="712" ury="718"/> + <char name="U" width="722" llx="123" lly="-19" urx="797" ury="718"/> + <char name="Uacute" width="722" llx="123" lly="-19" urx="797" ury="929"/> + <char name="Ucircumflex" width="722" llx="123" lly="-19" urx="797" ury="929"/> + <char name="Udieresis" width="722" llx="123" lly="-19" urx="797" ury="901"/> + <char name="Ugrave" width="722" llx="123" lly="-19" urx="797" ury="929"/> + <char name="V" width="667" llx="173" lly="0" urx="800" ury="718"/> + <char name="W" width="944" llx="169" lly="0" urx="1081" ury="718"/> + <char name="X" width="667" llx="19" lly="0" urx="790" ury="718"/> + <char name="Y" width="667" llx="167" lly="0" urx="806" ury="718"/> + <char name="Yacute" width="667" llx="167" lly="0" urx="806" ury="929"/> + <char name="Ydieresis" width="667" llx="167" lly="0" urx="806" ury="901"/> + <char name="Z" width="611" llx="23" lly="0" urx="741" ury="718"/> + <char name="Zcaron" width="611" llx="23" lly="0" urx="741" ury="929"/> + <char name="a" width="556" llx="61" lly="-15" urx="559" ury="538"/> + <char name="aacute" width="556" llx="61" lly="-15" urx="587" ury="734"/> + <char name="acircumflex" width="556" llx="61" lly="-15" urx="559" ury="734"/> + <char name="acute" width="333" llx="248" lly="593" urx="475" ury="734"/> + <char name="adieresis" width="556" llx="61" lly="-15" urx="559" ury="706"/> + <char name="ae" width="889" llx="61" lly="-15" urx="909" ury="538"/> + <char name="agrave" width="556" llx="61" lly="-15" urx="559" ury="734"/> + <char name="ampersand" width="667" llx="77" lly="-15" urx="647" ury="718"/> + <char name="aring" width="556" llx="61" lly="-15" urx="559" ury="756"/> + <char name="asciicircum" width="469" llx="42" lly="264" urx="539" ury="688"/> + <char name="asciitilde" width="584" llx="111" lly="180" urx="580" ury="326"/> + <char name="asterisk" width="389" llx="165" lly="431" urx="475" ury="718"/> + <char name="at" width="1015" llx="215" lly="-19" urx="965" ury="737"/> + <char name="atilde" width="556" llx="61" lly="-15" urx="592" ury="722"/> + <char name="b" width="556" llx="58" lly="-15" urx="584" ury="718"/> + <char name="backslash" width="278" llx="140" lly="-19" urx="291" ury="737"/> + <char name="bar" width="260" llx="46" lly="-225" urx="332" ury="775"/> + <char name="braceleft" width="334" llx="92" lly="-196" urx="445" ury="722"/> + <char name="braceright" width="334" llx="0" lly="-196" urx="354" ury="722"/> + <char name="bracketleft" width="278" llx="21" lly="-196" urx="403" ury="722"/> + <char name="bracketright" width="278" llx="-14" lly="-196" urx="368" ury="722"/> + <char name="breve" width="333" llx="167" lly="595" urx="476" ury="731"/> + <char name="brokenbar" width="260" llx="62" lly="-150" urx="316" ury="700"/> + <char name="bullet" width="350" llx="91" lly="202" urx="413" ury="517"/> + <char name="c" width="500" llx="74" lly="-15" urx="553" ury="538"/> + <char name="caron" width="333" llx="177" lly="593" urx="468" ury="734"/> + <char name="ccedilla" width="500" llx="74" lly="-225" urx="553" ury="538"/> + <char name="cedilla" width="333" llx="2" lly="-225" urx="232" ury="0"/> + <char name="cent" width="556" llx="95" lly="-115" urx="584" ury="623"/> + <char name="circumflex" width="333" llx="147" lly="593" urx="438" ury="734"/> + <char name="colon" width="278" llx="87" lly="0" urx="301" ury="516"/> + <char name="comma" width="278" llx="56" lly="-147" urx="214" ury="106"/> + <char name="copyright" width="737" llx="54" lly="-19" urx="837" ury="737"/> + <char name="currency" width="556" llx="60" lly="99" urx="646" ury="603"/> + <char name="d" width="556" llx="84" lly="-15" urx="652" ury="718"/> + <char name="dagger" width="556" llx="135" lly="-159" urx="622" ury="718"/> + <char name="daggerdbl" width="556" llx="52" lly="-159" urx="623" ury="718"/> + <char name="degree" width="400" llx="169" lly="411" urx="468" ury="703"/> + <char name="dieresis" width="333" llx="168" lly="604" urx="443" ury="706"/> + <char name="divide" width="584" llx="85" lly="-19" urx="606" ury="524"/> + <char name="dollar" width="556" llx="69" lly="-115" urx="617" ury="775"/> + <char name="dotaccent" width="333" llx="249" lly="604" urx="362" ury="706"/> + <char name="dotlessi" width="278" llx="95" lly="0" urx="294" ury="523"/> + <char name="e" width="556" llx="84" lly="-15" urx="578" ury="538"/> + <char name="eacute" width="556" llx="84" lly="-15" urx="587" ury="734"/> + <char name="ecircumflex" width="556" llx="84" lly="-15" urx="578" ury="734"/> + <char name="edieresis" width="556" llx="84" lly="-15" urx="578" ury="706"/> + <char name="egrave" width="556" llx="84" lly="-15" urx="578" ury="734"/> + <char name="eight" width="556" llx="74" lly="-19" urx="607" ury="703"/> + <char name="ellipsis" width="1000" llx="115" lly="0" urx="908" ury="106"/> + <char name="emdash" width="1000" llx="51" lly="240" urx="1067" ury="313"/> + <char name="endash" width="556" llx="51" lly="240" urx="623" ury="313"/> + <char name="equal" width="584" llx="63" lly="115" urx="628" ury="390"/> + <char name="eth" width="556" llx="81" lly="-15" urx="617" ury="737"/> + <char name="exclam" width="278" llx="90" lly="0" urx="340" ury="718"/> + <char name="exclamdown" width="333" llx="77" lly="-195" urx="326" ury="523"/> + <char name="f" width="278" llx="86" lly="0" urx="416" ury="728"/> + <char name="fi" width="500" llx="86" lly="0" urx="587" ury="728"/> + <char name="five" width="556" llx="68" lly="-19" urx="621" ury="688"/> + <char name="fl" width="500" llx="86" lly="0" urx="585" ury="728"/> + <char name="florin" width="556" llx="-52" lly="-207" urx="654" ury="737"/> + <char name="four" width="556" llx="61" lly="0" urx="576" ury="703"/> + <char name="fraction" width="167" llx="-170" lly="-19" urx="482" ury="703"/> + <char name="g" width="556" llx="42" lly="-220" urx="610" ury="538"/> + <char name="germandbls" width="611" llx="67" lly="-15" urx="658" ury="728"/> + <char name="grave" width="333" llx="170" lly="593" urx="337" ury="734"/> + <char name="greater" width="584" llx="50" lly="11" urx="597" ury="495"/> + <char name="guillemotleft" width="556" llx="146" lly="108" urx="554" ury="446"/> + <char name="guillemotright" width="556" llx="120" lly="108" urx="528" ury="446"/> + <char name="guilsinglleft" width="333" llx="137" lly="108" urx="340" ury="446"/> + <char name="guilsinglright" width="333" llx="111" lly="108" urx="314" ury="446"/> + <char name="h" width="556" llx="65" lly="0" urx="573" ury="718"/> + <char name="hungarumlaut" width="333" llx="157" lly="593" urx="565" ury="734"/> + <char name="hyphen" width="333" llx="93" lly="232" urx="357" ury="322"/> + <char name="i" width="222" llx="67" lly="0" urx="308" ury="718"/> + <char name="iacute" width="278" llx="95" lly="0" urx="448" ury="734"/> + <char name="icircumflex" width="278" llx="95" lly="0" urx="411" ury="734"/> + <char name="idieresis" width="278" llx="95" lly="0" urx="416" ury="706"/> + <char name="igrave" width="278" llx="95" lly="0" urx="310" ury="734"/> + <char name="j" width="222" llx="-60" lly="-210" urx="308" ury="718"/> + <char name="k" width="500" llx="67" lly="0" urx="600" ury="718"/> + <char name="l" width="222" llx="67" lly="0" urx="308" ury="718"/> + <char name="less" width="584" llx="94" lly="11" urx="641" ury="495"/> + <char name="logicalnot" width="584" llx="106" lly="108" urx="628" ury="390"/> + <char name="lslash" width="222" llx="41" lly="0" urx="347" ury="718"/> + <char name="m" width="833" llx="65" lly="0" urx="852" ury="538"/> + <char name="macron" width="333" llx="143" lly="627" urx="468" ury="684"/> + <char name="minus" width="584" llx="85" lly="216" urx="606" ury="289"/> + <char name="mu" width="556" llx="24" lly="-207" urx="600" ury="523"/> + <char name="multiply" width="584" llx="50" lly="0" urx="642" ury="506"/> + <char name="n" width="556" llx="65" lly="0" urx="573" ury="538"/> + <char name="nine" width="556" llx="82" lly="-19" urx="609" ury="703"/> + <char name="ntilde" width="556" llx="65" lly="0" urx="592" ury="722"/> + <char name="numbersign" width="556" llx="73" lly="0" urx="631" ury="688"/> + <char name="o" width="556" llx="83" lly="-14" urx="585" ury="538"/> + <char name="oacute" width="556" llx="83" lly="-14" urx="587" ury="734"/> + <char name="ocircumflex" width="556" llx="83" lly="-14" urx="585" ury="734"/> + <char name="odieresis" width="556" llx="83" lly="-14" urx="585" ury="706"/> + <char name="oe" width="944" llx="83" lly="-15" urx="964" ury="538"/> + <char name="ogonek" width="333" llx="43" lly="-225" urx="249" ury="0"/> + <char name="ograve" width="556" llx="83" lly="-14" urx="585" ury="734"/> + <char name="one" width="556" llx="207" lly="0" urx="508" ury="703"/> + <char name="onehalf" width="834" llx="114" lly="-19" urx="839" ury="703"/> + <char name="onequarter" width="834" llx="150" lly="-19" urx="802" ury="703"/> + <char name="onesuperior" width="333" llx="166" lly="281" urx="371" ury="703"/> + <char name="ordfeminine" width="370" llx="127" lly="405" urx="449" ury="737"/> + <char name="ordmasculine" width="365" llx="141" lly="405" urx="468" ury="737"/> + <char name="oslash" width="611" llx="29" lly="-22" urx="647" ury="545"/> + <char name="otilde" width="556" llx="83" lly="-14" urx="602" ury="722"/> + <char name="p" width="556" llx="14" lly="-207" urx="584" ury="538"/> + <char name="paragraph" width="537" llx="126" lly="-173" urx="650" ury="718"/> + <char name="parenleft" width="333" llx="108" lly="-207" urx="454" ury="733"/> + <char name="parenright" width="333" llx="-9" lly="-207" urx="337" ury="733"/> + <char name="percent" width="889" llx="147" lly="-19" urx="889" ury="703"/> + <char name="period" width="278" llx="87" lly="0" urx="214" ury="106"/> + <char name="periodcentered" width="278" llx="129" lly="190" urx="257" ury="315"/> + <char name="perthousand" width="1000" llx="88" lly="-19" urx="1029" ury="703"/> + <char name="plus" width="584" llx="85" lly="0" urx="606" ury="505"/> + <char name="plusminus" width="584" llx="39" lly="0" urx="618" ury="506"/> + <char name="q" width="556" llx="84" lly="-207" urx="605" ury="538"/> + <char name="question" width="556" llx="161" lly="0" urx="610" ury="727"/> + <char name="questiondown" width="611" llx="85" lly="-201" urx="534" ury="525"/> + <char name="quotedbl" width="355" llx="168" lly="463" urx="438" ury="718"/> + <char name="quotedblbase" width="333" llx="-6" lly="-149" urx="318" ury="106"/> + <char name="quotedblleft" width="333" llx="138" lly="470" urx="461" ury="725"/> + <char name="quotedblright" width="333" llx="124" lly="463" urx="448" ury="718"/> + <char name="quoteleft" width="222" llx="165" lly="470" urx="323" ury="725"/> + <char name="quoteright" width="222" llx="151" lly="463" urx="310" ury="718"/> + <char name="quotesinglbase" width="222" llx="21" lly="-149" urx="180" ury="106"/> + <char name="quotesingle" width="191" llx="157" lly="463" urx="285" ury="718"/> + <char name="r" width="333" llx="77" lly="0" urx="446" ury="538"/> + <char name="registered" width="737" llx="54" lly="-19" urx="837" ury="737"/> + <char name="ring" width="333" llx="214" lly="572" urx="402" ury="756"/> + <char name="s" width="500" llx="63" lly="-15" urx="529" ury="538"/> + <char name="scaron" width="500" llx="63" lly="-15" urx="552" ury="734"/> + <char name="section" width="556" llx="76" lly="-191" urx="584" ury="737"/> + <char name="semicolon" width="278" llx="56" lly="-147" urx="301" ury="516"/> + <char name="seven" width="556" llx="137" lly="0" urx="669" ury="688"/> + <char name="six" width="556" llx="91" lly="-19" urx="615" ury="703"/> + <char name="slash" width="278" llx="-21" lly="-19" urx="452" ury="737"/> + <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="278"/> - <char name="sterling" width="556"/> - <char name="t" width="278"/> - <char name="thorn" width="556"/> - <char name="three" width="556"/> - <char name="threequarters" width="834"/> - <char name="threesuperior" width="333"/> - <char name="tilde" width="333"/> - <char name="trademark" width="1000"/> - <char name="two" width="556"/> - <char name="twosuperior" width="333"/> - <char name="u" width="556"/> - <char name="uacute" width="556"/> - <char name="ucircumflex" width="556"/> - <char name="udieresis" width="556"/> - <char name="ugrave" width="556"/> - <char name="underscore" width="556"/> - <char name="v" width="500"/> - <char name="w" width="722"/> - <char name="x" width="500"/> - <char name="y" width="500"/> - <char name="yacute" width="500"/> - <char name="ydieresis" width="500"/> - <char name="yen" width="556"/> - <char name="z" width="500"/> - <char name="zcaron" width="500"/> - <char name="zero" width="556"/> - </widths> + <char name="sterling" width="556" llx="49" lly="-16" urx="634" ury="718"/> + <char name="t" width="278" llx="102" lly="-7" urx="368" ury="669"/> + <char name="thorn" width="556" llx="14" lly="-207" urx="584" ury="718"/> + <char name="three" width="556" llx="75" lly="-19" urx="610" ury="703"/> + <char name="threequarters" width="834" llx="130" lly="-19" urx="861" ury="703"/> + <char name="threesuperior" width="333" llx="90" lly="270" urx="436" ury="703"/> + <char name="tilde" width="333" llx="125" lly="606" urx="490" ury="722"/> + <char name="trademark" width="1000" llx="186" lly="306" urx="1056" ury="718"/> + <char name="two" width="556" llx="26" lly="0" urx="617" ury="703"/> + <char name="twosuperior" width="333" llx="64" lly="281" urx="449" ury="703"/> + <char name="u" width="556" llx="94" lly="-15" urx="600" ury="523"/> + <char name="uacute" width="556" llx="94" lly="-15" urx="600" ury="734"/> + <char name="ucircumflex" width="556" llx="94" lly="-15" urx="600" ury="734"/> + <char name="udieresis" width="556" llx="94" lly="-15" urx="600" ury="706"/> + <char name="ugrave" width="556" llx="94" lly="-15" urx="600" ury="734"/> + <char name="underscore" width="556" llx="-27" lly="-125" urx="540" ury="-75"/> + <char name="v" width="500" llx="119" lly="0" urx="603" ury="523"/> + <char name="w" width="722" llx="125" lly="0" urx="820" ury="523"/> + <char name="x" width="500" llx="11" lly="0" urx="594" ury="523"/> + <char name="y" width="500" llx="15" lly="-214" urx="600" ury="523"/> + <char name="yacute" width="500" llx="15" lly="-214" urx="600" ury="734"/> + <char name="ydieresis" width="500" llx="15" lly="-214" urx="600" ury="706"/> + <char name="yen" width="556" llx="81" lly="0" urx="699" ury="688"/> + <char name="z" width="500" llx="31" lly="0" urx="571" ury="523"/> + <char name="zcaron" width="500" llx="31" lly="0" urx="571" ury="734"/> + <char name="zero" width="556" llx="93" lly="-19" urx="608" ury="703"/> + </char-metrics> <kerning kpx1="107"> <pair kern="-20" kpx2="111"/> <pair kern="-20" kpx2="101"/> @@ -602,4 +603,4 @@ <pair kern="-30" kpx2="118"/> <pair kern="-15" kpx2="44"/> </kerning> -</font-metrics>
\ No newline at end of file +</font-metrics> diff --git a/src/codegen/fonts/Symbol.xml b/src/codegen/fonts/Symbol.xml index c0dce043a..7493b7e7f 100644 --- a/src/codegen/fonts/Symbol.xml +++ b/src/codegen/fonts/Symbol.xml @@ -21,203 +21,204 @@ <family-name>Symbol</family-name> <class-name>Symbol</class-name> <encoding>SymbolEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>1010</cap-height> <x-height>520</x-height> <ascender>1010</ascender> <descender>-293</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="space" width="250"/> - <char name="exclam" width="333"/> - <char name="universal" width="713"/> - <char name="numbersign" width="500"/> - <char name="existential" width="549"/> - <char name="percent" width="833"/> - <char name="ampersand" width="778"/> - <char name="suchthat" width="439"/> - <char name="parenleft" width="333"/> - <char name="parenright" width="333"/> - <char name="asteriskmath" width="500"/> - <char name="plus" width="549"/> - <char name="comma" width="250"/> - <char name="minus" width="549"/> - <char name="period" width="250"/> - <char name="slash" width="278"/> - <char name="zero" width="500"/> - <char name="one" width="500"/> - <char name="two" width="500"/> - <char name="three" width="500"/> - <char name="four" width="500"/> - <char name="five" width="500"/> - <char name="six" width="500"/> - <char name="seven" width="500"/> - <char name="eight" width="500"/> - <char name="nine" width="500"/> - <char name="colon" width="278"/> - <char name="semicolon" width="278"/> - <char name="less" width="549"/> - <char name="equal" width="549"/> - <char name="greater" width="549"/> - <char name="question" width="444"/> - <char name="congruent" width="549"/> - <char name="Alpha" width="722"/> - <char name="Beta" width="667"/> - <char name="Chi" width="722"/> - <char name="Delta" width="612"/> - <char name="Epsilon" width="611"/> - <char name="Phi" width="763"/> - <char name="Gamma" width="603"/> - <char name="Eta" width="722"/> - <char name="Iota" width="333"/> - <char name="theta1" width="631"/> - <char name="Kappa" width="722"/> - <char name="Lambda" width="686"/> - <char name="Mu" width="889"/> - <char name="Nu" width="722"/> - <char name="Omicron" width="722"/> - <char name="Pi" width="768"/> - <char name="Theta" width="741"/> - <char name="Rho" width="556"/> - <char name="Sigma" width="592"/> - <char name="Tau" width="611"/> - <char name="Upsilon" width="690"/> - <char name="sigma1" width="439"/> - <char name="Omega" width="768"/> - <char name="Xi" width="645"/> - <char name="Psi" width="795"/> - <char name="Zeta" width="611"/> - <char name="bracketleft" width="333"/> - <char name="therefore" width="863"/> - <char name="bracketright" width="333"/> - <char name="perpendicular" width="658"/> - <char name="underscore" width="500"/> - <char name="radicalex" width="500"/> - <char name="alpha" width="631"/> - <char name="beta" width="549"/> - <char name="chi" width="549"/> - <char name="delta" width="494"/> - <char name="epsilon" width="439"/> - <char name="phi" width="521"/> - <char name="gamma" width="411"/> - <char name="eta" width="603"/> - <char name="iota" width="329"/> - <char name="phi1" width="603"/> - <char name="kappa" width="549"/> - <char name="lambda" width="549"/> - <char name="m" width="576"/> - <char name="mu" width="576"/> - <char name="nu" width="521"/> - <char name="omicron" width="549"/> - <char name="pi" width="549"/> - <char name="theta" width="521"/> - <char name="rho" width="549"/> - <char name="sigma" width="603"/> - <char name="tau" width="439"/> - <char name="upsilon" width="576"/> - <char name="omega1" width="713"/> - <char name="omega" width="686"/> - <char name="xi" width="493"/> - <char name="psi" width="686"/> - <char name="zeta" width="494"/> - <char name="braceleft" width="480"/> - <char name="bar" width="200"/> - <char name="braceright" width="480"/> - <char name="similar" width="549"/> - <char name="Euro" width="750"/> - <char name="Upsilon1" width="620"/> - <char name="minute" width="247"/> - <char name="lessequal" width="549"/> - <char name="fraction" width="167"/> - <char name="infinity" width="713"/> - <char name="florin" width="500"/> - <char name="club" width="753"/> - <char name="diamond" width="753"/> - <char name="heart" width="753"/> - <char name="spade" width="753"/> - <char name="arrowboth" width="1042"/> - <char name="arrowleft" width="987"/> - <char name="arrowup" width="603"/> - <char name="arrowright" width="987"/> - <char name="arrowdown" width="603"/> - <char name="degree" width="400"/> - <char name="plusminus" width="549"/> - <char name="second" width="411"/> - <char name="greaterequal" width="549"/> - <char name="multiply" width="549"/> - <char name="proportional" width="713"/> - <char name="partialdiff" width="494"/> - <char name="bullet" width="460"/> - <char name="divide" width="549"/> - <char name="notequal" width="549"/> - <char name="equivalence" width="549"/> - <char name="approxequal" width="549"/> - <char name="ellipsis" width="1000"/> - <char name="arrowvertex" width="603"/> - <char name="arrowhorizex" width="1000"/> - <char name="carriagereturn" width="658"/> - <char name="aleph" width="823"/> - <char name="Ifraktur" width="686"/> - <char name="Rfraktur" width="795"/> - <char name="weierstrass" width="987"/> - <char name="circlemultiply" width="768"/> - <char name="circleplus" width="768"/> - <char name="emptyset" width="823"/> - <char name="intersection" width="768"/> - <char name="union" width="768"/> - <char name="propersuperset" width="713"/> - <char name="reflexsuperset" width="713"/> - <char name="notsubset" width="713"/> - <char name="propersubset" width="713"/> - <char name="reflexsubset" width="713"/> - <char name="element" width="713"/> - <char name="notelement" width="713"/> - <char name="angle" width="768"/> - <char name="gradient" width="713"/> - <char name="registerserif" width="790"/> - <char name="copyrightserif" width="790"/> - <char name="trademarkserif" width="890"/> - <char name="product" width="823"/> - <char name="radical" width="549"/> - <char name="dotmath" width="250"/> - <char name="logicalnot" width="713"/> - <char name="logicaland" width="603"/> - <char name="logicalor" width="603"/> - <char name="arrowdblboth" width="1042"/> - <char name="arrowdblleft" width="987"/> - <char name="arrowdblup" width="603"/> - <char name="arrowdblright" width="987"/> - <char name="arrowdbldown" width="603"/> - <char name="lozenge" width="494"/> - <char name="angleleft" width="329"/> - <char name="registersans" width="790"/> - <char name="copyrightsans" width="790"/> - <char name="trademarksans" width="786"/> - <char name="summation" width="713"/> - <char name="parenlefttp" width="384"/> - <char name="parenleftex" width="384"/> - <char name="parenleftbt" width="384"/> - <char name="bracketlefttp" width="384"/> - <char name="bracketleftex" width="384"/> - <char name="bracketleftbt" width="384"/> - <char name="bracelefttp" width="494"/> - <char name="braceleftmid" width="494"/> - <char name="braceleftbt" width="494"/> - <char name="braceex" width="494"/> - <char name="angleright" width="329"/> - <char name="integral" width="274"/> - <char name="integraltp" width="686"/> - <char name="integralex" width="686"/> - <char name="integralbt" width="686"/> - <char name="parenrighttp" width="384"/> - <char name="parenrightex" width="384"/> - <char name="parenrightbt" width="384"/> - <char name="bracketrighttp" width="384"/> - <char name="bracketrightex" width="384"/> - <char name="bracketrightbt" width="384"/> - <char name="bracerighttp" width="494"/> - <char name="bracerightmid" width="494"/> - <char name="bracerightbt" width="494"/> - <char name="apple" width="790"/> - </widths> + <char-metrics> + <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/> + <char name="exclam" width="333" llx="128" lly="-17" urx="240" ury="672"/> + <char name="universal" width="713" llx="31" lly="0" urx="681" ury="705"/> + <char name="numbersign" width="500" llx="20" lly="-16" urx="481" ury="673"/> + <char name="existential" width="549" llx="25" lly="0" urx="478" ury="707"/> + <char name="percent" width="833" llx="63" lly="-36" urx="771" ury="655"/> + <char name="ampersand" width="778" llx="41" lly="-18" urx="750" ury="661"/> + <char name="suchthat" width="439" llx="48" lly="-17" urx="414" ury="500"/> + <char name="parenleft" width="333" llx="53" lly="-191" urx="300" ury="673"/> + <char name="parenright" width="333" llx="30" lly="-191" urx="277" ury="673"/> + <char name="asteriskmath" width="500" llx="65" lly="134" urx="427" ury="551"/> + <char name="plus" width="549" llx="10" lly="0" urx="539" ury="533"/> + <char name="comma" width="250" llx="56" lly="-152" urx="194" ury="104"/> + <char name="minus" width="549" llx="11" lly="233" urx="535" ury="288"/> + <char name="period" width="250" llx="69" lly="-17" urx="181" ury="95"/> + <char name="slash" width="278" llx="0" lly="-18" urx="254" ury="646"/> + <char name="zero" width="500" llx="24" lly="-14" urx="476" ury="685"/> + <char name="one" width="500" llx="117" lly="0" urx="390" ury="673"/> + <char name="two" width="500" llx="25" lly="0" urx="475" ury="685"/> + <char name="three" width="500" llx="43" lly="-14" urx="435" ury="685"/> + <char name="four" width="500" llx="15" lly="0" urx="469" ury="685"/> + <char name="five" width="500" llx="32" lly="-14" urx="445" ury="690"/> + <char name="six" width="500" llx="34" lly="-14" urx="468" ury="685"/> + <char name="seven" width="500" llx="24" lly="-16" urx="448" ury="673"/> + <char name="eight" width="500" llx="56" lly="-14" urx="445" ury="685"/> + <char name="nine" width="500" llx="30" lly="-18" urx="459" ury="685"/> + <char name="colon" width="278" llx="81" lly="-17" urx="193" ury="460"/> + <char name="semicolon" width="278" llx="83" lly="-152" urx="221" ury="460"/> + <char name="less" width="549" llx="26" lly="0" urx="523" ury="522"/> + <char name="equal" width="549" llx="11" lly="141" urx="537" ury="390"/> + <char name="greater" width="549" llx="26" lly="0" urx="523" ury="522"/> + <char name="question" width="444" llx="70" lly="-17" urx="412" ury="686"/> + <char name="congruent" width="549" llx="11" lly="0" urx="537" ury="475"/> + <char name="Alpha" width="722" llx="4" lly="0" urx="684" ury="673"/> + <char name="Beta" width="667" llx="29" lly="0" urx="592" ury="673"/> + <char name="Chi" width="722" llx="-9" lly="0" urx="704" ury="673"/> + <char name="Delta" width="612" llx="6" lly="0" urx="608" ury="688"/> + <char name="Epsilon" width="611" llx="32" lly="0" urx="617" ury="673"/> + <char name="Phi" width="763" llx="26" lly="0" urx="741" ury="673"/> + <char name="Gamma" width="603" llx="24" lly="0" urx="609" ury="673"/> + <char name="Eta" width="722" llx="39" lly="0" urx="729" ury="673"/> + <char name="Iota" width="333" llx="32" lly="0" urx="316" ury="673"/> + <char name="theta1" width="631" llx="18" lly="-18" urx="623" ury="689"/> + <char name="Kappa" width="722" llx="35" lly="0" urx="722" ury="673"/> + <char name="Lambda" width="686" llx="6" lly="0" urx="680" ury="688"/> + <char name="Mu" width="889" llx="28" lly="0" urx="887" ury="673"/> + <char name="Nu" width="722" llx="29" lly="-8" urx="720" ury="673"/> + <char name="Omicron" width="722" llx="41" lly="-17" urx="715" ury="685"/> + <char name="Pi" width="768" llx="25" lly="0" urx="745" ury="673"/> + <char name="Theta" width="741" llx="41" lly="-17" urx="715" ury="685"/> + <char name="Rho" width="556" llx="28" lly="0" urx="563" ury="673"/> + <char name="Sigma" width="592" llx="5" lly="0" urx="589" ury="673"/> + <char name="Tau" width="611" llx="33" lly="0" urx="607" ury="673"/> + <char name="Upsilon" width="690" llx="-8" lly="0" urx="694" ury="673"/> + <char name="sigma1" width="439" llx="40" lly="-233" urx="436" ury="500"/> + <char name="Omega" width="768" llx="34" lly="0" urx="736" ury="688"/> + <char name="Xi" width="645" llx="40" lly="0" urx="599" ury="673"/> + <char name="Psi" width="795" llx="15" lly="0" urx="781" ury="684"/> + <char name="Zeta" width="611" llx="44" lly="0" urx="636" ury="673"/> + <char name="bracketleft" width="333" llx="86" lly="-155" urx="299" ury="674"/> + <char name="therefore" width="863" llx="163" lly="0" urx="701" ury="487"/> + <char name="bracketright" width="333" llx="33" lly="-155" urx="246" ury="674"/> + <char name="perpendicular" width="658" llx="15" lly="0" urx="652" ury="674"/> + <char name="underscore" width="500" llx="-2" lly="-125" urx="502" ury="-75"/> + <char name="radicalex" width="500" llx="480" lly="881" urx="1090" ury="917"/> + <char name="alpha" width="631" llx="41" lly="-18" urx="622" ury="500"/> + <char name="beta" width="549" llx="61" lly="-223" urx="515" ury="741"/> + <char name="chi" width="549" llx="12" lly="-231" urx="522" ury="499"/> + <char name="delta" width="494" llx="40" lly="-19" urx="481" ury="740"/> + <char name="epsilon" width="439" llx="22" lly="-19" urx="427" ury="502"/> + <char name="phi" width="521" llx="28" lly="-224" urx="492" ury="673"/> + <char name="gamma" width="411" llx="5" lly="-225" urx="484" ury="499"/> + <char name="eta" width="603" llx="0" lly="-202" urx="527" ury="514"/> + <char name="iota" width="329" llx="0" lly="-17" urx="301" ury="503"/> + <char name="phi1" width="603" llx="36" lly="-224" urx="587" ury="499"/> + <char name="kappa" width="549" llx="33" lly="0" urx="558" ury="501"/> + <char name="lambda" width="549" llx="24" lly="-17" urx="548" ury="739"/> + <char name="mu" width="576" llx="33" lly="-223" urx="567" ury="500"/> + <char name="nu" width="521" llx="-9" lly="-16" urx="475" ury="507"/> + <char name="omicron" width="549" llx="35" lly="-19" urx="501" ury="499"/> + <char name="pi" width="549" llx="10" lly="-19" urx="530" ury="487"/> + <char name="theta" width="521" llx="43" lly="-17" urx="485" ury="690"/> + <char name="rho" width="549" llx="50" lly="-230" urx="490" ury="499"/> + <char name="sigma" width="603" llx="30" lly="-21" urx="588" ury="500"/> + <char name="tau" width="439" llx="10" lly="-19" urx="418" ury="500"/> + <char name="upsilon" width="576" llx="7" lly="-18" urx="535" ury="507"/> + <char name="omega1" width="713" llx="12" lly="-18" urx="671" ury="583"/> + <char name="omega" width="686" llx="42" lly="-17" urx="684" ury="500"/> + <char name="xi" width="493" llx="27" lly="-224" urx="469" ury="766"/> + <char name="psi" width="686" llx="12" lly="-228" urx="701" ury="500"/> + <char name="zeta" width="494" llx="60" lly="-225" urx="467" ury="756"/> + <char name="braceleft" width="480" llx="58" lly="-183" urx="397" ury="673"/> + <char name="bar" width="200" llx="65" lly="-293" urx="135" ury="707"/> + <char name="braceright" width="480" llx="79" lly="-183" urx="418" ury="673"/> + <char name="similar" width="549" llx="17" lly="203" urx="529" ury="307"/> + <char name="Euro" width="750" llx="20" lly="-12" urx="714" ury="685"/> + <char name="Upsilon1" width="620" llx="-2" lly="0" urx="610" ury="685"/> + <char name="minute" width="247" llx="27" lly="459" urx="228" ury="735"/> + <char name="lessequal" width="549" llx="29" lly="0" urx="526" ury="639"/> + <char name="fraction" width="167" llx="-180" lly="-12" urx="340" ury="677"/> + <char name="infinity" width="713" llx="26" lly="124" urx="688" ury="404"/> + <char name="florin" width="500" llx="2" lly="-193" urx="494" ury="686"/> + <char name="club" width="753" llx="86" lly="-26" urx="660" ury="533"/> + <char name="diamond" width="753" llx="142" lly="-36" urx="600" ury="550"/> + <char name="heart" width="753" llx="117" lly="-33" urx="631" ury="532"/> + <char name="spade" width="753" llx="113" lly="-36" urx="629" ury="548"/> + <char name="arrowboth" width="1042" llx="24" lly="-15" urx="1024" ury="511"/> + <char name="arrowleft" width="987" llx="32" lly="-15" urx="942" ury="511"/> + <char name="arrowup" width="603" llx="45" lly="0" urx="571" ury="910"/> + <char name="arrowright" width="987" llx="49" lly="-15" urx="959" ury="511"/> + <char name="arrowdown" width="603" llx="45" lly="-22" urx="571" ury="888"/> + <char name="degree" width="400" llx="50" lly="385" urx="350" ury="685"/> + <char name="plusminus" width="549" llx="10" lly="0" urx="539" ury="645"/> + <char name="second" width="411" llx="20" lly="459" urx="413" ury="737"/> + <char name="greaterequal" width="549" llx="29" lly="0" urx="526" ury="639"/> + <char name="multiply" width="549" llx="17" lly="8" urx="533" ury="524"/> + <char name="proportional" width="713" llx="27" lly="123" urx="639" ury="404"/> + <char name="partialdiff" width="494" llx="26" lly="-20" urx="462" ury="746"/> + <char name="bullet" width="460" llx="50" lly="113" urx="410" ury="473"/> + <char name="divide" width="549" llx="10" lly="71" urx="536" ury="456"/> + <char name="notequal" width="549" llx="15" lly="-25" urx="540" ury="549"/> + <char name="equivalence" width="549" llx="14" lly="82" urx="538" ury="443"/> + <char name="approxequal" width="549" llx="14" lly="135" urx="527" ury="394"/> + <char name="ellipsis" width="1000" llx="111" lly="-17" urx="889" ury="95"/> + <char name="arrowvertex" width="603" llx="280" lly="-120" urx="336" ury="1010"/> + <char name="arrowhorizex" width="1000" llx="-60" lly="220" urx="1050" ury="276"/> + <char name="carriagereturn" width="658" llx="15" lly="-16" urx="602" ury="629"/> + <char name="aleph" width="823" llx="175" lly="-18" urx="661" ury="658"/> + <char name="Ifraktur" width="686" llx="10" lly="-53" urx="578" ury="740"/> + <char name="Rfraktur" width="795" llx="26" lly="-15" urx="759" ury="734"/> + <char name="weierstrass" width="987" llx="159" lly="-211" urx="870" ury="573"/> + <char name="circlemultiply" width="768" llx="43" lly="-17" urx="733" ury="673"/> + <char name="circleplus" width="768" llx="43" lly="-15" urx="733" ury="675"/> + <char name="emptyset" width="823" llx="39" lly="-24" urx="781" ury="719"/> + <char name="intersection" width="768" llx="40" lly="0" urx="732" ury="509"/> + <char name="union" width="768" llx="40" lly="-17" urx="732" ury="492"/> + <char name="propersuperset" width="713" llx="20" lly="0" urx="673" ury="470"/> + <char name="reflexsuperset" width="713" llx="20" lly="-125" urx="673" ury="470"/> + <char name="notsubset" width="713" llx="36" lly="-70" urx="690" ury="540"/> + <char name="propersubset" width="713" llx="37" lly="0" urx="690" ury="470"/> + <char name="reflexsubset" width="713" llx="37" lly="-125" urx="690" ury="470"/> + <char name="element" width="713" llx="45" lly="0" urx="505" ury="468"/> + <char name="notelement" width="713" llx="45" lly="-58" urx="505" ury="555"/> + <char name="angle" width="768" llx="26" lly="0" urx="738" ury="673"/> + <char name="gradient" width="713" llx="36" lly="-19" urx="681" ury="718"/> + <char name="registerserif" width="790" llx="50" lly="-17" urx="740" ury="673"/> + <char name="copyrightserif" width="790" llx="51" lly="-15" urx="741" ury="675"/> + <char name="trademarkserif" width="890" llx="18" lly="293" urx="855" ury="673"/> + <char name="product" width="823" llx="25" lly="-101" urx="803" ury="751"/> + <char name="radical" width="549" llx="10" lly="-38" urx="515" ury="917"/> + <char name="dotmath" width="250" llx="69" lly="210" urx="169" ury="310"/> + <char name="logicalnot" width="713" llx="15" lly="0" urx="680" ury="288"/> + <char name="logicaland" width="603" llx="23" lly="0" urx="583" ury="454"/> + <char name="logicalor" width="603" llx="30" lly="0" urx="578" ury="477"/> + <char name="arrowdblboth" width="1042" llx="27" lly="-20" urx="1023" ury="510"/> + <char name="arrowdblleft" width="987" llx="30" lly="-15" urx="939" ury="513"/> + <char name="arrowdblup" width="603" llx="39" lly="2" urx="567" ury="911"/> + <char name="arrowdblright" width="987" llx="45" lly="-20" urx="954" ury="508"/> + <char name="arrowdbldown" width="603" llx="44" lly="-19" urx="572" ury="890"/> + <char name="lozenge" width="494" llx="18" lly="0" urx="466" ury="745"/> + <char name="angleleft" width="329" llx="25" lly="-198" urx="306" ury="746"/> + <char name="registersans" width="790" llx="50" lly="-20" urx="740" ury="670"/> + <char name="copyrightsans" width="790" llx="49" lly="-15" urx="739" ury="675"/> + <char name="trademarksans" width="786" llx="5" lly="293" urx="725" ury="673"/> + <char name="summation" width="713" llx="14" lly="-108" urx="695" ury="752"/> + <char name="parenlefttp" width="384" llx="24" lly="-293" urx="436" ury="926"/> + <char name="parenleftex" width="384" llx="24" lly="-85" urx="108" ury="925"/> + <char name="parenleftbt" width="384" llx="24" lly="-293" urx="436" ury="926"/> + <char name="bracketlefttp" width="384" llx="0" lly="-80" urx="349" ury="926"/> + <char name="bracketleftex" width="384" llx="0" lly="-79" urx="77" ury="925"/> + <char name="bracketleftbt" width="384" llx="0" lly="-80" urx="349" ury="926"/> + <char name="bracelefttp" width="494" llx="209" lly="-85" urx="445" ury="925"/> + <char name="braceleftmid" width="494" llx="20" lly="-85" urx="284" ury="935"/> + <char name="braceleftbt" width="494" llx="209" lly="-75" urx="445" ury="935"/> + <char name="braceex" width="494" llx="209" lly="-85" urx="284" ury="935"/> + <char name="angleright" width="329" llx="21" lly="-198" urx="302" ury="746"/> + <char name="integral" width="274" llx="2" lly="-107" urx="291" ury="916"/> + <char name="integraltp" width="686" llx="308" lly="-88" urx="675" ury="920"/> + <char name="integralex" width="686" llx="308" lly="-88" urx="378" ury="975"/> + <char name="integralbt" width="686" llx="11" lly="-87" urx="378" ury="921"/> + <char name="parenrighttp" width="384" llx="54" lly="-293" urx="466" ury="926"/> + <char name="parenrightex" width="384" llx="382" lly="-85" urx="466" ury="925"/> + <char name="parenrightbt" width="384" llx="54" lly="-293" urx="466" ury="926"/> + <char name="bracketrighttp" width="384" llx="22" lly="-80" urx="371" ury="926"/> + <char name="bracketrightex" width="384" llx="294" lly="-79" urx="371" ury="925"/> + <char name="bracketrightbt" width="384" llx="22" lly="-80" urx="371" ury="926"/> + <char name="bracerighttp" width="494" llx="48" lly="-85" urx="284" ury="925"/> + <char name="bracerightmid" width="494" llx="209" lly="-85" urx="473" ury="935"/> + <char name="bracerightbt" width="494" llx="48" lly="-75" urx="284" ury="935"/> + <char name="apple" width="790" llx="56" lly="-3" urx="733" ury="808"/> + </char-metrics> </font-metrics> diff --git a/src/codegen/fonts/TimesBold.xml b/src/codegen/fonts/TimesBold.xml index 20d50fdd8..ef5d6bcc0 100644 --- a/src/codegen/fonts/TimesBold.xml +++ b/src/codegen/fonts/TimesBold.xml @@ -22,245 +22,246 @@ <family-name>Times</family-name> <class-name>TimesBold</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>676</cap-height> <x-height>461</x-height> <ascender>676</ascender> <descender>-205</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="722"/> - <char name="AE" width="1000"/> - <char name="Aacute" width="722"/> - <char name="Acircumflex" width="722"/> - <char name="Adieresis" width="722"/> - <char name="Agrave" width="722"/> - <char name="Aring" width="722"/> - <char name="Atilde" width="722"/> - <char name="B" width="667"/> - <char name="C" width="722"/> - <char name="Ccedilla" width="722"/> - <char name="D" width="722"/> - <char name="E" width="667"/> - <char name="Eacute" width="667"/> - <char name="Ecircumflex" width="667"/> - <char name="Edieresis" width="667"/> - <char name="Egrave" width="667"/> - <char name="Eth" width="722"/> - <char name="Euro" width="500"/> - <char name="F" width="611"/> - <char name="G" width="778"/> - <char name="H" width="778"/> - <char name="I" width="389"/> - <char name="Iacute" width="389"/> - <char name="Icircumflex" width="389"/> - <char name="Idieresis" width="389"/> - <char name="Igrave" width="389"/> - <char name="J" width="500"/> - <char name="K" width="778"/> - <char name="L" width="667"/> - <char name="Lslash" width="667"/> - <char name="M" width="944"/> - <char name="N" width="722"/> - <char name="Ntilde" width="722"/> - <char name="O" width="778"/> - <char name="OE" width="1000"/> - <char name="Oacute" width="778"/> - <char name="Ocircumflex" width="778"/> - <char name="Odieresis" width="778"/> - <char name="Ograve" width="778"/> - <char name="Oslash" width="778"/> - <char name="Otilde" width="778"/> - <char name="P" width="611"/> - <char name="Q" width="778"/> - <char name="R" width="722"/> - <char name="S" width="556"/> - <char name="Scaron" width="556"/> - <char name="T" width="667"/> - <char name="Thorn" width="611"/> - <char name="U" width="722"/> - <char name="Uacute" width="722"/> - <char name="Ucircumflex" width="722"/> - <char name="Udieresis" width="722"/> - <char name="Ugrave" width="722"/> - <char name="V" width="722"/> - <char name="W" width="1000"/> - <char name="X" width="722"/> - <char name="Y" width="722"/> - <char name="Yacute" width="722"/> - <char name="Ydieresis" width="722"/> - <char name="Z" width="667"/> - <char name="Zcaron" width="667"/> - <char name="a" width="500"/> - <char name="aacute" width="500"/> - <char name="acircumflex" width="500"/> - <char name="acute" width="333"/> - <char name="adieresis" width="500"/> - <char name="ae" width="722"/> - <char name="agrave" width="500"/> - <char name="ampersand" width="833"/> - <char name="aring" width="500"/> - <char name="asciicircum" width="581"/> - <char name="asciitilde" width="520"/> - <char name="asterisk" width="500"/> - <char name="at" width="930"/> - <char name="atilde" width="500"/> - <char name="b" width="556"/> - <char name="backslash" width="278"/> - <char name="bar" width="220"/> - <char name="braceleft" width="394"/> - <char name="braceright" width="394"/> - <char name="bracketleft" width="333"/> - <char name="bracketright" width="333"/> - <char name="breve" width="333"/> - <char name="brokenbar" width="220"/> - <char name="bullet" width="350"/> - <char name="c" width="444"/> - <char name="caron" width="333"/> - <char name="ccedilla" width="444"/> - <char name="cedilla" width="333"/> - <char name="cent" width="500"/> - <char name="circumflex" width="333"/> - <char name="colon" width="333"/> - <char name="comma" width="250"/> - <char name="copyright" width="747"/> - <char name="currency" width="500"/> - <char name="d" width="556"/> - <char name="dagger" width="500"/> - <char name="daggerdbl" width="500"/> - <char name="degree" width="400"/> - <char name="dieresis" width="333"/> - <char name="divide" width="570"/> - <char name="dollar" width="500"/> - <char name="dotaccent" width="333"/> - <char name="dotlessi" width="278"/> - <char name="e" width="444"/> - <char name="eacute" width="444"/> - <char name="ecircumflex" width="444"/> - <char name="edieresis" width="444"/> - <char name="egrave" width="444"/> - <char name="eight" width="500"/> - <char name="ellipsis" width="1000"/> - <char name="emdash" width="1000"/> - <char name="endash" width="500"/> - <char name="equal" width="570"/> - <char name="eth" width="500"/> - <char name="exclam" width="333"/> - <char name="exclamdown" width="333"/> - <char name="f" width="333"/> - <char name="fi" width="556"/> - <char name="five" width="500"/> - <char name="fl" width="556"/> - <char name="florin" width="500"/> - <char name="four" width="500"/> - <char name="fraction" width="167"/> - <char name="g" width="500"/> - <char name="germandbls" width="556"/> - <char name="grave" width="333"/> - <char name="greater" width="570"/> - <char name="guillemotleft" width="500"/> - <char name="guillemotright" width="500"/> - <char name="guilsinglleft" width="333"/> - <char name="guilsinglright" width="333"/> - <char name="h" width="556"/> - <char name="hungarumlaut" width="333"/> - <char name="hyphen" width="333"/> - <char name="i" width="278"/> - <char name="iacute" width="278"/> - <char name="icircumflex" width="278"/> - <char name="idieresis" width="278"/> - <char name="igrave" width="278"/> - <char name="j" width="333"/> - <char name="k" width="556"/> - <char name="l" width="278"/> - <char name="less" width="570"/> - <char name="logicalnot" width="570"/> - <char name="lslash" width="278"/> - <char name="m" width="833"/> - <char name="macron" width="333"/> - <char name="minus" width="324"/> - <char name="mu" width="556"/> - <char name="multiply" width="570"/> - <char name="n" width="556"/> - <char name="nine" width="500"/> - <char name="ntilde" width="556"/> - <char name="numbersign" width="500"/> - <char name="o" width="500"/> - <char name="oacute" width="500"/> - <char name="ocircumflex" width="500"/> - <char name="odieresis" width="500"/> - <char name="oe" width="722"/> - <char name="ogonek" width="333"/> - <char name="ograve" width="500"/> - <char name="one" width="500"/> - <char name="onehalf" width="750"/> - <char name="onequarter" width="750"/> - <char name="onesuperior" width="300"/> - <char name="ordfeminine" width="300"/> - <char name="ordmasculine" width="330"/> - <char name="oslash" width="500"/> - <char name="otilde" width="500"/> - <char name="p" width="556"/> - <char name="paragraph" width="540"/> - <char name="parenleft" width="333"/> - <char name="parenright" width="333"/> - <char name="percent" width="1000"/> - <char name="period" width="250"/> - <char name="periodcentered" width="250"/> - <char name="perthousand" width="1000"/> - <char name="plus" width="570"/> - <char name="plusminus" width="570"/> - <char name="q" width="556"/> - <char name="question" width="500"/> - <char name="questiondown" width="500"/> - <char name="quotedbl" width="555"/> - <char name="quotedblbase" width="500"/> - <char name="quotedblleft" width="500"/> - <char name="quotedblright" width="500"/> - <char name="quoteleft" width="333"/> - <char name="quoteright" width="333"/> - <char name="quotesinglbase" width="333"/> - <char name="quotesingle" width="278"/> - <char name="r" width="444"/> - <char name="registered" width="747"/> - <char name="ring" width="333"/> - <char name="s" width="389"/> - <char name="scaron" width="389"/> - <char name="section" width="500"/> - <char name="semicolon" width="333"/> - <char name="seven" width="500"/> - <char name="six" width="500"/> - <char name="slash" width="278"/> - <char name="space" width="250"/> + <char-metrics> + <char name="A" width="722" llx="9" lly="0" urx="689" ury="690"/> + <char name="AE" width="1000" llx="4" lly="0" urx="951" ury="676"/> + <char name="Aacute" width="722" llx="9" lly="0" urx="689" ury="923"/> + <char name="Acircumflex" width="722" llx="9" lly="0" urx="689" ury="914"/> + <char name="Adieresis" width="722" llx="9" lly="0" urx="689" ury="877"/> + <char name="Agrave" width="722" llx="9" lly="0" urx="689" ury="923"/> + <char name="Aring" width="722" llx="9" lly="0" urx="689" ury="935"/> + <char name="Atilde" width="722" llx="9" lly="0" urx="689" ury="884"/> + <char name="B" width="667" llx="16" lly="0" urx="619" ury="676"/> + <char name="C" width="722" llx="49" lly="-19" urx="687" ury="691"/> + <char name="Ccedilla" width="722" llx="49" lly="-218" urx="687" ury="691"/> + <char name="D" width="722" llx="14" lly="0" urx="690" ury="676"/> + <char name="E" width="667" llx="16" lly="0" urx="641" ury="676"/> + <char name="Eacute" width="667" llx="16" lly="0" urx="641" ury="923"/> + <char name="Ecircumflex" width="667" llx="16" lly="0" urx="641" ury="914"/> + <char name="Edieresis" width="667" llx="16" lly="0" urx="641" ury="877"/> + <char name="Egrave" width="667" llx="16" lly="0" urx="641" ury="923"/> + <char name="Eth" width="722" llx="6" lly="0" urx="690" ury="676"/> + <char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="611" llx="16" lly="0" urx="583" ury="676"/> + <char name="G" width="778" llx="37" lly="-19" urx="755" ury="691"/> + <char name="H" width="778" llx="21" lly="0" urx="759" ury="676"/> + <char name="I" width="389" llx="20" lly="0" urx="370" ury="676"/> + <char name="Iacute" width="389" llx="20" lly="0" urx="370" ury="923"/> + <char name="Icircumflex" width="389" llx="20" lly="0" urx="370" ury="914"/> + <char name="Idieresis" width="389" llx="20" lly="0" urx="370" ury="877"/> + <char name="Igrave" width="389" llx="20" lly="0" urx="370" ury="923"/> + <char name="J" width="500" llx="3" lly="-96" urx="479" ury="676"/> + <char name="K" width="778" llx="30" lly="0" urx="769" ury="676"/> + <char name="L" width="667" llx="19" lly="0" urx="638" ury="676"/> + <char name="Lslash" width="667" llx="19" lly="0" urx="638" ury="676"/> + <char name="M" width="944" llx="14" lly="0" urx="921" ury="676"/> + <char name="N" width="722" llx="16" lly="-18" urx="701" ury="676"/> + <char name="Ntilde" width="722" llx="16" lly="-18" urx="701" ury="884"/> + <char name="O" width="778" llx="35" lly="-19" urx="743" ury="691"/> + <char name="OE" width="1000" llx="22" lly="-5" urx="981" ury="684"/> + <char name="Oacute" width="778" llx="35" lly="-19" urx="743" ury="923"/> + <char name="Ocircumflex" width="778" llx="35" lly="-19" urx="743" ury="914"/> + <char name="Odieresis" width="778" llx="35" lly="-19" urx="743" ury="877"/> + <char name="Ograve" width="778" llx="35" lly="-19" urx="743" ury="923"/> + <char name="Oslash" width="778" llx="35" lly="-74" urx="743" ury="737"/> + <char name="Otilde" width="778" llx="35" lly="-19" urx="743" ury="884"/> + <char name="P" width="611" llx="16" lly="0" urx="600" ury="676"/> + <char name="Q" width="778" llx="35" lly="-176" urx="743" ury="691"/> + <char name="R" width="722" llx="26" lly="0" urx="715" ury="676"/> + <char name="S" width="556" llx="35" lly="-19" urx="513" ury="692"/> + <char name="Scaron" width="556" llx="35" lly="-19" urx="513" ury="914"/> + <char name="T" width="667" llx="31" lly="0" urx="636" ury="676"/> + <char name="Thorn" width="611" llx="16" lly="0" urx="600" ury="676"/> + <char name="U" width="722" llx="16" lly="-19" urx="701" ury="676"/> + <char name="Uacute" width="722" llx="16" lly="-19" urx="701" ury="923"/> + <char name="Ucircumflex" width="722" llx="16" lly="-19" urx="701" ury="914"/> + <char name="Udieresis" width="722" llx="16" lly="-19" urx="701" ury="877"/> + <char name="Ugrave" width="722" llx="16" lly="-19" urx="701" ury="923"/> + <char name="V" width="722" llx="16" lly="-18" urx="701" ury="676"/> + <char name="W" width="1000" llx="19" lly="-15" urx="981" ury="676"/> + <char name="X" width="722" llx="16" lly="0" urx="699" ury="676"/> + <char name="Y" width="722" llx="15" lly="0" urx="699" ury="676"/> + <char name="Yacute" width="722" llx="15" lly="0" urx="699" ury="923"/> + <char name="Ydieresis" width="722" llx="15" lly="0" urx="699" ury="877"/> + <char name="Z" width="667" llx="28" lly="0" urx="634" ury="676"/> + <char name="Zcaron" width="667" llx="28" lly="0" urx="634" ury="914"/> + <char name="a" width="500" llx="25" lly="-14" urx="488" ury="473"/> + <char name="aacute" width="500" llx="25" lly="-14" urx="488" ury="713"/> + <char name="acircumflex" width="500" llx="25" lly="-14" urx="488" ury="704"/> + <char name="acute" width="333" llx="86" lly="528" urx="324" ury="713"/> + <char name="adieresis" width="500" llx="25" lly="-14" urx="488" ury="667"/> + <char name="ae" width="722" llx="33" lly="-14" urx="693" ury="473"/> + <char name="agrave" width="500" llx="25" lly="-14" urx="488" ury="713"/> + <char name="ampersand" width="833" llx="62" lly="-16" urx="787" ury="691"/> + <char name="aring" width="500" llx="25" lly="-14" urx="488" ury="740"/> + <char name="asciicircum" width="581" llx="73" lly="311" urx="509" ury="676"/> + <char name="asciitilde" width="520" llx="29" lly="173" urx="491" ury="333"/> + <char name="asterisk" width="500" llx="56" lly="255" urx="447" ury="691"/> + <char name="at" width="930" llx="108" lly="-19" urx="822" ury="691"/> + <char name="atilde" width="500" llx="25" lly="-14" urx="488" ury="674"/> + <char name="b" width="556" llx="17" lly="-14" urx="521" ury="676"/> + <char name="backslash" width="278" llx="-25" lly="-19" urx="303" ury="691"/> + <char name="bar" width="220" llx="66" lly="-218" urx="154" ury="782"/> + <char name="braceleft" width="394" llx="22" lly="-175" urx="340" ury="698"/> + <char name="braceright" width="394" llx="54" lly="-175" urx="372" ury="698"/> + <char name="bracketleft" width="333" llx="67" lly="-149" urx="301" ury="678"/> + <char name="bracketright" width="333" llx="32" lly="-149" urx="266" ury="678"/> + <char name="breve" width="333" llx="15" lly="528" urx="318" ury="691"/> + <char name="brokenbar" width="220" llx="66" lly="-143" urx="154" ury="707"/> + <char name="bullet" width="350" llx="35" lly="198" urx="315" ury="478"/> + <char name="c" width="444" llx="25" lly="-14" urx="430" ury="473"/> + <char name="caron" width="333" llx="-2" lly="528" urx="335" ury="704"/> + <char name="ccedilla" width="444" llx="25" lly="-218" urx="430" ury="473"/> + <char name="cedilla" width="333" llx="68" lly="-218" urx="294" ury="0"/> + <char name="cent" width="500" llx="53" lly="-140" urx="458" ury="588"/> + <char name="circumflex" width="333" llx="-2" lly="528" urx="335" ury="704"/> + <char name="colon" width="333" llx="82" lly="-13" urx="251" ury="472"/> + <char name="comma" width="250" llx="39" lly="-180" urx="223" ury="155"/> + <char name="copyright" width="747" llx="26" lly="-19" urx="721" ury="691"/> + <char name="currency" width="500" llx="-26" lly="61" urx="526" ury="613"/> + <char name="d" width="556" llx="25" lly="-14" urx="534" ury="676"/> + <char name="dagger" width="500" llx="47" lly="-134" urx="453" ury="691"/> + <char name="daggerdbl" width="500" llx="45" lly="-132" urx="456" ury="691"/> + <char name="degree" width="400" llx="57" lly="402" urx="343" ury="688"/> + <char name="dieresis" width="333" llx="-2" lly="537" urx="335" ury="667"/> + <char name="divide" width="570" llx="33" lly="-31" urx="537" ury="537"/> + <char name="dollar" width="500" llx="29" lly="-99" urx="472" ury="750"/> + <char name="dotaccent" width="333" llx="103" lly="536" urx="258" ury="691"/> + <char name="dotlessi" width="278" llx="16" lly="0" urx="255" ury="461"/> + <char name="e" width="444" llx="25" lly="-14" urx="426" ury="473"/> + <char name="eacute" width="444" llx="25" lly="-14" urx="426" ury="713"/> + <char name="ecircumflex" width="444" llx="25" lly="-14" urx="426" ury="704"/> + <char name="edieresis" width="444" llx="25" lly="-14" urx="426" ury="667"/> + <char name="egrave" width="444" llx="25" lly="-14" urx="426" ury="713"/> + <char name="eight" width="500" llx="28" lly="-13" urx="472" ury="688"/> + <char name="ellipsis" width="1000" llx="82" lly="-13" urx="917" ury="156"/> + <char name="emdash" width="1000" llx="0" lly="181" urx="1000" ury="271"/> + <char name="endash" width="500" llx="0" lly="181" urx="500" ury="271"/> + <char name="equal" width="570" llx="33" lly="107" urx="537" ury="399"/> + <char name="eth" width="500" llx="25" lly="-14" urx="476" ury="691"/> + <char name="exclam" width="333" llx="81" lly="-13" urx="251" ury="691"/> + <char name="exclamdown" width="333" llx="82" lly="-203" urx="252" ury="501"/> + <char name="f" width="333" llx="14" lly="0" urx="389" ury="691"/> + <char name="fi" width="556" llx="14" lly="0" urx="536" ury="691"/> + <char name="five" width="500" llx="22" lly="-8" urx="470" ury="676"/> + <char name="fl" width="556" llx="14" lly="0" urx="536" ury="691"/> + <char name="florin" width="500" llx="0" lly="-155" urx="498" ury="706"/> + <char name="four" width="500" llx="19" lly="0" urx="475" ury="688"/> + <char name="fraction" width="167" llx="-168" lly="-12" urx="329" ury="688"/> + <char name="g" width="500" llx="28" lly="-206" urx="483" ury="473"/> + <char name="germandbls" width="556" llx="19" lly="-12" urx="517" ury="691"/> + <char name="grave" width="333" llx="8" lly="528" urx="246" ury="713"/> + <char name="greater" width="570" llx="31" lly="-8" urx="539" ury="514"/> + <char name="guillemotleft" width="500" llx="23" lly="36" urx="473" ury="415"/> + <char name="guillemotright" width="500" llx="27" lly="36" urx="477" ury="415"/> + <char name="guilsinglleft" width="333" llx="51" lly="36" urx="305" ury="415"/> + <char name="guilsinglright" width="333" llx="28" lly="36" urx="282" ury="415"/> + <char name="h" width="556" llx="16" lly="0" urx="534" ury="676"/> + <char name="hungarumlaut" width="333" llx="-13" lly="528" urx="425" ury="713"/> + <char name="hyphen" width="333" llx="44" lly="171" urx="287" ury="287"/> + <char name="i" width="278" llx="16" lly="0" urx="255" ury="691"/> + <char name="iacute" width="278" llx="16" lly="0" urx="289" ury="713"/> + <char name="icircumflex" width="278" llx="-37" lly="0" urx="300" ury="704"/> + <char name="idieresis" width="278" llx="-37" lly="0" urx="300" ury="667"/> + <char name="igrave" width="278" llx="-27" lly="0" urx="255" ury="713"/> + <char name="j" width="333" llx="-57" lly="-203" urx="263" ury="691"/> + <char name="k" width="556" llx="22" lly="0" urx="543" ury="676"/> + <char name="l" width="278" llx="16" lly="0" urx="255" ury="676"/> + <char name="less" width="570" llx="31" lly="-8" urx="539" ury="514"/> + <char name="logicalnot" width="570" llx="33" lly="108" urx="537" ury="399"/> + <char name="lslash" width="278" llx="-22" lly="0" urx="303" ury="676"/> + <char name="m" width="833" llx="16" lly="0" urx="814" ury="473"/> + <char name="macron" width="333" llx="1" lly="565" urx="331" ury="637"/> + <char name="minus" width="324" llx="33" lly="209" urx="537" ury="297"/> + <char name="mu" width="556" llx="33" lly="-206" urx="536" ury="461"/> + <char name="multiply" width="570" llx="48" lly="16" urx="522" ury="490"/> + <char name="n" width="556" llx="21" lly="0" urx="539" ury="473"/> + <char name="nine" width="500" llx="26" lly="-13" urx="473" ury="688"/> + <char name="ntilde" width="556" llx="21" lly="0" urx="539" ury="674"/> + <char name="numbersign" width="500" llx="4" lly="0" urx="496" ury="700"/> + <char name="o" width="500" llx="25" lly="-14" urx="476" ury="473"/> + <char name="oacute" width="500" llx="25" lly="-14" urx="476" ury="713"/> + <char name="ocircumflex" width="500" llx="25" lly="-14" urx="476" ury="704"/> + <char name="odieresis" width="500" llx="25" lly="-14" urx="476" ury="667"/> + <char name="oe" width="722" llx="22" lly="-14" urx="696" ury="473"/> + <char name="ogonek" width="333" llx="90" lly="-193" urx="319" ury="24"/> + <char name="ograve" width="500" llx="25" lly="-14" urx="476" ury="713"/> + <char name="one" width="500" llx="65" lly="0" urx="442" ury="688"/> + <char name="onehalf" width="750" llx="-7" lly="-12" urx="775" ury="688"/> + <char name="onequarter" width="750" llx="28" lly="-12" urx="743" ury="688"/> + <char name="onesuperior" width="300" llx="28" lly="275" urx="273" ury="688"/> + <char name="ordfeminine" width="300" llx="-1" lly="397" urx="301" ury="688"/> + <char name="ordmasculine" width="330" llx="18" lly="397" urx="312" ury="688"/> + <char name="oslash" width="500" llx="25" lly="-92" urx="476" ury="549"/> + <char name="otilde" width="500" llx="25" lly="-14" urx="476" ury="674"/> + <char name="p" width="556" llx="19" lly="-205" urx="524" ury="473"/> + <char name="paragraph" width="540" llx="0" lly="-186" urx="519" ury="676"/> + <char name="parenleft" width="333" llx="46" lly="-168" urx="306" ury="694"/> + <char name="parenright" width="333" llx="27" lly="-168" urx="287" ury="694"/> + <char name="percent" width="1000" llx="124" lly="-14" urx="877" ury="692"/> + <char name="period" width="250" llx="41" lly="-13" urx="210" ury="156"/> + <char name="periodcentered" width="250" llx="41" lly="248" urx="210" ury="417"/> + <char name="perthousand" width="1000" llx="7" lly="-29" urx="995" ury="706"/> + <char name="plus" width="570" llx="33" lly="0" urx="537" ury="506"/> + <char name="plusminus" width="570" llx="33" lly="0" urx="537" ury="506"/> + <char name="q" width="556" llx="34" lly="-205" urx="536" ury="473"/> + <char name="question" width="500" llx="57" lly="-13" urx="445" ury="689"/> + <char name="questiondown" width="500" llx="55" lly="-201" urx="443" ury="501"/> + <char name="quotedbl" width="555" llx="83" lly="404" urx="472" ury="691"/> + <char name="quotedblbase" width="500" llx="14" lly="-180" urx="468" ury="155"/> + <char name="quotedblleft" width="500" llx="32" lly="356" urx="486" ury="691"/> + <char name="quotedblright" width="500" llx="14" lly="356" urx="468" ury="691"/> + <char name="quoteleft" width="333" llx="70" lly="356" urx="254" ury="691"/> + <char name="quoteright" width="333" llx="79" lly="356" urx="263" ury="691"/> + <char name="quotesinglbase" width="333" llx="79" lly="-180" urx="263" ury="155"/> + <char name="quotesingle" width="278" llx="75" lly="404" urx="204" ury="691"/> + <char name="r" width="444" llx="29" lly="0" urx="434" ury="473"/> + <char name="registered" width="747" llx="26" lly="-19" urx="721" ury="691"/> + <char name="ring" width="333" llx="60" lly="527" urx="273" ury="740"/> + <char name="s" width="389" llx="25" lly="-14" urx="361" ury="473"/> + <char name="scaron" width="389" llx="25" lly="-14" urx="363" ury="704"/> + <char name="section" width="500" llx="57" lly="-132" urx="443" ury="691"/> + <char name="semicolon" width="333" llx="82" lly="-180" urx="266" ury="472"/> + <char name="seven" width="500" llx="17" lly="0" urx="477" ury="676"/> + <char name="six" width="500" llx="28" lly="-13" urx="475" ury="688"/> + <char name="slash" width="278" llx="-24" lly="-19" urx="302" ury="691"/> + <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="250"/> - <char name="sterling" width="500"/> - <char name="t" width="333"/> - <char name="thorn" width="556"/> - <char name="three" width="500"/> - <char name="threequarters" width="750"/> - <char name="threesuperior" width="300"/> - <char name="tilde" width="333"/> - <char name="trademark" width="1000"/> - <char name="two" width="500"/> - <char name="twosuperior" width="300"/> - <char name="u" width="556"/> - <char name="uacute" width="556"/> - <char name="ucircumflex" width="556"/> - <char name="udieresis" width="556"/> - <char name="ugrave" width="556"/> - <char name="underscore" width="500"/> - <char name="v" width="500"/> - <char name="w" width="722"/> - <char name="x" width="500"/> - <char name="y" width="500"/> - <char name="yacute" width="500"/> - <char name="ydieresis" width="500"/> - <char name="yen" width="500"/> - <char name="z" width="444"/> - <char name="zcaron" width="444"/> - <char name="zero" width="500"/> - </widths> + <char name="sterling" width="500" llx="21" lly="-14" urx="477" ury="684"/> + <char name="t" width="333" llx="20" lly="-12" urx="332" ury="630"/> + <char name="thorn" width="556" llx="19" lly="-205" urx="524" ury="676"/> + <char name="three" width="500" llx="16" lly="-14" urx="468" ury="688"/> + <char name="threequarters" width="750" llx="23" lly="-12" urx="733" ury="688"/> + <char name="threesuperior" width="300" llx="3" lly="268" urx="297" ury="688"/> + <char name="tilde" width="333" llx="-16" lly="547" urx="349" ury="674"/> + <char name="trademark" width="1000" llx="24" lly="271" urx="977" ury="676"/> + <char name="two" width="500" llx="17" lly="0" urx="478" ury="688"/> + <char name="twosuperior" width="300" llx="0" lly="275" urx="300" ury="688"/> + <char name="u" width="556" llx="16" lly="-14" urx="537" ury="461"/> + <char name="uacute" width="556" llx="16" lly="-14" urx="537" ury="713"/> + <char name="ucircumflex" width="556" llx="16" lly="-14" urx="537" ury="704"/> + <char name="udieresis" width="556" llx="16" lly="-14" urx="537" ury="667"/> + <char name="ugrave" width="556" llx="16" lly="-14" urx="537" ury="713"/> + <char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/> + <char name="v" width="500" llx="21" lly="-14" urx="485" ury="461"/> + <char name="w" width="722" llx="23" lly="-14" urx="707" ury="461"/> + <char name="x" width="500" llx="12" lly="0" urx="484" ury="461"/> + <char name="y" width="500" llx="16" lly="-205" urx="480" ury="461"/> + <char name="yacute" width="500" llx="16" lly="-205" urx="480" ury="713"/> + <char name="ydieresis" width="500" llx="16" lly="-205" urx="480" ury="667"/> + <char name="yen" width="500" llx="-64" lly="0" urx="547" ury="676"/> + <char name="z" width="444" llx="21" lly="0" urx="420" ury="461"/> + <char name="zcaron" width="444" llx="21" lly="0" urx="420" ury="704"/> + <char name="zero" width="500" llx="24" lly="-13" urx="476" ury="688"/> + </char-metrics> <kerning kpx1="79"> <pair kern="-40" kpx2="65"/> <pair kern="-50" kpx2="87"/> diff --git a/src/codegen/fonts/TimesBoldItalic.xml b/src/codegen/fonts/TimesBoldItalic.xml index d1b70872a..ec67369f2 100644 --- a/src/codegen/fonts/TimesBoldItalic.xml +++ b/src/codegen/fonts/TimesBoldItalic.xml @@ -22,245 +22,246 @@ <family-name>Times</family-name> <class-name>TimesBoldItalic</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>669</cap-height> <x-height>462</x-height> <ascender>699</ascender> <descender>-205</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="667"/> - <char name="AE" width="944"/> - <char name="Aacute" width="667"/> - <char name="Acircumflex" width="667"/> - <char name="Adieresis" width="667"/> - <char name="Agrave" width="667"/> - <char name="Aring" width="667"/> - <char name="Atilde" width="667"/> - <char name="B" width="667"/> - <char name="C" width="667"/> - <char name="Ccedilla" width="667"/> - <char name="D" width="722"/> - <char name="E" width="667"/> - <char name="Eacute" width="667"/> - <char name="Ecircumflex" width="667"/> - <char name="Edieresis" width="667"/> - <char name="Egrave" width="667"/> - <char name="Eth" width="722"/> - <char name="Euro" width="500"/> - <char name="F" width="667"/> - <char name="G" width="722"/> - <char name="H" width="778"/> - <char name="I" width="389"/> - <char name="Iacute" width="389"/> - <char name="Icircumflex" width="389"/> - <char name="Idieresis" width="389"/> - <char name="Igrave" width="389"/> - <char name="J" width="500"/> - <char name="K" width="667"/> - <char name="L" width="611"/> - <char name="Lslash" width="611"/> - <char name="M" width="889"/> - <char name="N" width="722"/> - <char name="Ntilde" width="722"/> - <char name="O" width="722"/> - <char name="OE" width="944"/> - <char name="Oacute" width="722"/> - <char name="Ocircumflex" width="722"/> - <char name="Odieresis" width="722"/> - <char name="Ograve" width="722"/> - <char name="Oslash" width="722"/> - <char name="Otilde" width="722"/> - <char name="P" width="611"/> - <char name="Q" width="722"/> - <char name="R" width="667"/> - <char name="S" width="556"/> - <char name="Scaron" width="556"/> - <char name="T" width="611"/> - <char name="Thorn" width="611"/> - <char name="U" width="722"/> - <char name="Uacute" width="722"/> - <char name="Ucircumflex" width="722"/> - <char name="Udieresis" width="722"/> - <char name="Ugrave" width="722"/> - <char name="V" width="667"/> - <char name="W" width="889"/> - <char name="X" width="667"/> - <char name="Y" width="611"/> - <char name="Yacute" width="611"/> - <char name="Ydieresis" width="611"/> - <char name="Z" width="611"/> - <char name="Zcaron" width="611"/> - <char name="a" width="500"/> - <char name="aacute" width="500"/> - <char name="acircumflex" width="500"/> - <char name="acute" width="333"/> - <char name="adieresis" width="500"/> - <char name="ae" width="722"/> - <char name="agrave" width="500"/> - <char name="ampersand" width="778"/> - <char name="aring" width="500"/> - <char name="asciicircum" width="570"/> - <char name="asciitilde" width="570"/> - <char name="asterisk" width="500"/> - <char name="at" width="832"/> - <char name="atilde" width="500"/> - <char name="b" width="500"/> - <char name="backslash" width="278"/> - <char name="bar" width="220"/> - <char name="braceleft" width="348"/> - <char name="braceright" width="348"/> - <char name="bracketleft" width="333"/> - <char name="bracketright" width="333"/> - <char name="breve" width="333"/> - <char name="brokenbar" width="220"/> - <char name="bullet" width="350"/> - <char name="c" width="444"/> - <char name="caron" width="333"/> - <char name="ccedilla" width="444"/> - <char name="cedilla" width="333"/> - <char name="cent" width="500"/> - <char name="circumflex" width="333"/> - <char name="colon" width="333"/> - <char name="comma" width="250"/> - <char name="copyright" width="747"/> - <char name="currency" width="500"/> - <char name="d" width="500"/> - <char name="dagger" width="500"/> - <char name="daggerdbl" width="500"/> - <char name="degree" width="400"/> - <char name="dieresis" width="333"/> - <char name="divide" width="570"/> - <char name="dollar" width="500"/> - <char name="dotaccent" width="333"/> - <char name="dotlessi" width="278"/> - <char name="e" width="444"/> - <char name="eacute" width="444"/> - <char name="ecircumflex" width="444"/> - <char name="edieresis" width="444"/> - <char name="egrave" width="444"/> - <char name="eight" width="500"/> - <char name="ellipsis" width="1000"/> - <char name="emdash" width="1000"/> - <char name="endash" width="500"/> - <char name="equal" width="570"/> - <char name="eth" width="500"/> - <char name="exclam" width="389"/> - <char name="exclamdown" width="389"/> - <char name="f" width="333"/> - <char name="fi" width="556"/> - <char name="five" width="500"/> - <char name="fl" width="556"/> - <char name="florin" width="500"/> - <char name="four" width="500"/> - <char name="fraction" width="167"/> - <char name="g" width="500"/> - <char name="germandbls" width="500"/> - <char name="grave" width="333"/> - <char name="greater" width="570"/> - <char name="guillemotleft" width="500"/> - <char name="guillemotright" width="500"/> - <char name="guilsinglleft" width="333"/> - <char name="guilsinglright" width="333"/> - <char name="h" width="556"/> - <char name="hungarumlaut" width="333"/> - <char name="hyphen" width="333"/> - <char name="i" width="278"/> - <char name="iacute" width="278"/> - <char name="icircumflex" width="278"/> - <char name="idieresis" width="278"/> - <char name="igrave" width="278"/> - <char name="j" width="278"/> - <char name="k" width="500"/> - <char name="l" width="278"/> - <char name="less" width="570"/> - <char name="logicalnot" width="606"/> - <char name="lslash" width="278"/> - <char name="m" width="778"/> - <char name="macron" width="333"/> - <char name="minus" width="330"/> - <char name="mu" width="576"/> - <char name="multiply" width="570"/> - <char name="n" width="556"/> - <char name="nine" width="500"/> - <char name="ntilde" width="556"/> - <char name="numbersign" width="500"/> - <char name="o" width="500"/> - <char name="oacute" width="500"/> - <char name="ocircumflex" width="500"/> - <char name="odieresis" width="500"/> - <char name="oe" width="722"/> - <char name="ogonek" width="333"/> - <char name="ograve" width="500"/> - <char name="one" width="500"/> - <char name="onehalf" width="750"/> - <char name="onequarter" width="750"/> - <char name="onesuperior" width="300"/> - <char name="ordfeminine" width="266"/> - <char name="ordmasculine" width="300"/> - <char name="oslash" width="500"/> - <char name="otilde" width="500"/> - <char name="p" width="500"/> - <char name="paragraph" width="500"/> - <char name="parenleft" width="333"/> - <char name="parenright" width="333"/> - <char name="percent" width="833"/> - <char name="period" width="250"/> - <char name="periodcentered" width="250"/> - <char name="perthousand" width="1000"/> - <char name="plus" width="570"/> - <char name="plusminus" width="570"/> - <char name="q" width="500"/> - <char name="question" width="500"/> - <char name="questiondown" width="500"/> - <char name="quotedbl" width="555"/> - <char name="quotedblbase" width="500"/> - <char name="quotedblleft" width="500"/> - <char name="quotedblright" width="500"/> - <char name="quoteleft" width="333"/> - <char name="quoteright" width="333"/> - <char name="quotesinglbase" width="333"/> - <char name="quotesingle" width="278"/> - <char name="r" width="389"/> - <char name="registered" width="747"/> - <char name="ring" width="333"/> - <char name="s" width="389"/> - <char name="scaron" width="389"/> - <char name="section" width="500"/> - <char name="semicolon" width="333"/> - <char name="seven" width="500"/> - <char name="six" width="500"/> - <char name="slash" width="278"/> - <char name="space" width="250"/> + <char-metrics> + <char name="A" width="667" llx="-67" lly="0" urx="593" ury="683"/> + <char name="AE" width="944" llx="-64" lly="0" urx="918" ury="669"/> + <char name="Aacute" width="667" llx="-67" lly="0" urx="593" ury="904"/> + <char name="Acircumflex" width="667" llx="-67" lly="0" urx="593" ury="897"/> + <char name="Adieresis" width="667" llx="-67" lly="0" urx="593" ury="862"/> + <char name="Agrave" width="667" llx="-67" lly="0" urx="593" ury="904"/> + <char name="Aring" width="667" llx="-67" lly="0" urx="593" ury="921"/> + <char name="Atilde" width="667" llx="-67" lly="0" urx="593" ury="862"/> + <char name="B" width="667" llx="-24" lly="0" urx="624" ury="669"/> + <char name="C" width="667" llx="32" lly="-18" urx="677" ury="685"/> + <char name="Ccedilla" width="667" llx="32" lly="-218" urx="677" ury="685"/> + <char name="D" width="722" llx="-46" lly="0" urx="685" ury="669"/> + <char name="E" width="667" llx="-27" lly="0" urx="653" ury="669"/> + <char name="Eacute" width="667" llx="-27" lly="0" urx="653" ury="904"/> + <char name="Ecircumflex" width="667" llx="-27" lly="0" urx="653" ury="897"/> + <char name="Edieresis" width="667" llx="-27" lly="0" urx="653" ury="862"/> + <char name="Egrave" width="667" llx="-27" lly="0" urx="653" ury="904"/> + <char name="Eth" width="722" llx="-31" lly="0" urx="700" ury="669"/> + <char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="667" llx="-13" lly="0" urx="660" ury="669"/> + <char name="G" width="722" llx="21" lly="-18" urx="706" ury="685"/> + <char name="H" width="778" llx="-24" lly="0" urx="799" ury="669"/> + <char name="I" width="389" llx="-32" lly="0" urx="406" ury="669"/> + <char name="Iacute" width="389" llx="-32" lly="0" urx="432" ury="904"/> + <char name="Icircumflex" width="389" llx="-32" lly="0" urx="450" ury="897"/> + <char name="Idieresis" width="389" llx="-32" lly="0" urx="450" ury="862"/> + <char name="Igrave" width="389" llx="-32" lly="0" urx="406" ury="904"/> + <char name="J" width="500" llx="-46" lly="-99" urx="524" ury="669"/> + <char name="K" width="667" llx="-21" lly="0" urx="702" ury="669"/> + <char name="L" width="611" llx="-22" lly="0" urx="590" ury="669"/> + <char name="Lslash" width="611" llx="-22" lly="0" urx="590" ury="669"/> + <char name="M" width="889" llx="-29" lly="-12" urx="917" ury="669"/> + <char name="N" width="722" llx="-27" lly="-15" urx="748" ury="669"/> + <char name="Ntilde" width="722" llx="-27" lly="-15" urx="748" ury="862"/> + <char name="O" width="722" llx="27" lly="-18" urx="691" ury="685"/> + <char name="OE" width="944" llx="23" lly="-8" urx="946" ury="677"/> + <char name="Oacute" width="722" llx="27" lly="-18" urx="691" ury="904"/> + <char name="Ocircumflex" width="722" llx="27" lly="-18" urx="691" ury="897"/> + <char name="Odieresis" width="722" llx="27" lly="-18" urx="691" ury="862"/> + <char name="Ograve" width="722" llx="27" lly="-18" urx="691" ury="904"/> + <char name="Oslash" width="722" llx="27" lly="-125" urx="691" ury="764"/> + <char name="Otilde" width="722" llx="27" lly="-18" urx="691" ury="862"/> + <char name="P" width="611" llx="-27" lly="0" urx="613" ury="669"/> + <char name="Q" width="722" llx="27" lly="-208" urx="691" ury="685"/> + <char name="R" width="667" llx="-29" lly="0" urx="623" ury="669"/> + <char name="S" width="556" llx="2" lly="-18" urx="526" ury="685"/> + <char name="Scaron" width="556" llx="2" lly="-18" urx="553" ury="897"/> + <char name="T" width="611" llx="50" lly="0" urx="650" ury="669"/> + <char name="Thorn" width="611" llx="-27" lly="0" urx="573" ury="669"/> + <char name="U" width="722" llx="67" lly="-18" urx="744" ury="669"/> + <char name="Uacute" width="722" llx="67" lly="-18" urx="744" ury="904"/> + <char name="Ucircumflex" width="722" llx="67" lly="-18" urx="744" ury="897"/> + <char name="Udieresis" width="722" llx="67" lly="-18" urx="744" ury="862"/> + <char name="Ugrave" width="722" llx="67" lly="-18" urx="744" ury="904"/> + <char name="V" width="667" llx="65" lly="-18" urx="715" ury="669"/> + <char name="W" width="889" llx="65" lly="-18" urx="940" ury="669"/> + <char name="X" width="667" llx="-24" lly="0" urx="694" ury="669"/> + <char name="Y" width="611" llx="73" lly="0" urx="659" ury="669"/> + <char name="Yacute" width="611" llx="73" lly="0" urx="659" ury="904"/> + <char name="Ydieresis" width="611" llx="73" lly="0" urx="659" ury="862"/> + <char name="Z" width="611" llx="-11" lly="0" urx="590" ury="669"/> + <char name="Zcaron" width="611" llx="-11" lly="0" urx="590" ury="897"/> + <char name="a" width="500" llx="-21" lly="-14" urx="455" ury="462"/> + <char name="aacute" width="500" llx="-21" lly="-14" urx="463" ury="697"/> + <char name="acircumflex" width="500" llx="-21" lly="-14" urx="455" ury="690"/> + <char name="acute" width="333" llx="139" lly="516" urx="379" ury="697"/> + <char name="adieresis" width="500" llx="-21" lly="-14" urx="476" ury="655"/> + <char name="ae" width="722" llx="-5" lly="-13" urx="673" ury="462"/> + <char name="agrave" width="500" llx="-21" lly="-14" urx="455" ury="697"/> + <char name="ampersand" width="778" llx="5" lly="-19" urx="699" ury="682"/> + <char name="aring" width="500" llx="-21" lly="-14" urx="455" ury="729"/> + <char name="asciicircum" width="570" llx="67" lly="304" urx="503" ury="669"/> + <char name="asciitilde" width="570" llx="54" lly="173" urx="516" ury="333"/> + <char name="asterisk" width="500" llx="65" lly="249" urx="456" ury="685"/> + <char name="at" width="832" llx="63" lly="-18" urx="770" ury="685"/> + <char name="atilde" width="500" llx="-21" lly="-14" urx="491" ury="655"/> + <char name="b" width="500" llx="-14" lly="-13" urx="444" ury="699"/> + <char name="backslash" width="278" llx="-1" lly="-18" urx="279" ury="685"/> + <char name="bar" width="220" llx="66" lly="-218" urx="154" ury="782"/> + <char name="braceleft" width="348" llx="5" lly="-187" urx="436" ury="686"/> + <char name="braceright" width="348" llx="-129" lly="-187" urx="302" ury="686"/> + <char name="bracketleft" width="333" llx="-37" lly="-159" urx="362" ury="674"/> + <char name="bracketright" width="333" llx="-56" lly="-157" urx="343" ury="674"/> + <char name="breve" width="333" llx="71" lly="516" urx="387" ury="678"/> + <char name="brokenbar" width="220" llx="66" lly="-143" urx="154" ury="707"/> + <char name="bullet" width="350" llx="0" lly="175" urx="350" ury="525"/> + <char name="c" width="444" llx="-5" lly="-13" urx="392" ury="462"/> + <char name="caron" width="333" llx="79" lly="516" urx="411" ury="690"/> + <char name="ccedilla" width="444" llx="-5" lly="-218" urx="392" ury="462"/> + <char name="cedilla" width="333" llx="-80" lly="-218" urx="156" ury="5"/> + <char name="cent" width="500" llx="42" lly="-143" urx="439" ury="576"/> + <char name="circumflex" width="333" llx="40" lly="516" urx="367" ury="690"/> + <char name="colon" width="333" llx="23" lly="-13" urx="264" ury="459"/> + <char name="comma" width="250" llx="-60" lly="-182" urx="144" ury="134"/> + <char name="copyright" width="747" llx="30" lly="-18" urx="718" ury="685"/> + <char name="currency" width="500" llx="-26" lly="34" urx="526" ury="586"/> + <char name="d" width="500" llx="-21" lly="-13" urx="517" ury="699"/> + <char name="dagger" width="500" llx="91" lly="-145" urx="494" ury="685"/> + <char name="daggerdbl" width="500" llx="10" lly="-139" urx="493" ury="685"/> + <char name="degree" width="400" llx="83" lly="397" urx="369" ury="683"/> + <char name="dieresis" width="333" llx="55" lly="550" urx="402" ury="684"/> + <char name="divide" width="570" llx="33" lly="-29" urx="537" ury="535"/> + <char name="dollar" width="500" llx="-20" lly="-100" urx="497" ury="733"/> + <char name="dotaccent" width="333" llx="163" lly="550" urx="298" ury="684"/> + <char name="dotlessi" width="278" llx="2" lly="-9" urx="238" ury="462"/> + <char name="e" width="444" llx="5" lly="-13" urx="398" ury="462"/> + <char name="eacute" width="444" llx="5" lly="-13" urx="435" ury="697"/> + <char name="ecircumflex" width="444" llx="5" lly="-13" urx="423" ury="690"/> + <char name="edieresis" width="444" llx="5" lly="-13" urx="448" ury="655"/> + <char name="egrave" width="444" llx="5" lly="-13" urx="398" ury="697"/> + <char name="eight" width="500" llx="3" lly="-13" urx="476" ury="683"/> + <char name="ellipsis" width="1000" llx="40" lly="-13" urx="852" ury="135"/> + <char name="emdash" width="1000" llx="-40" lly="178" urx="977" ury="269"/> + <char name="endash" width="500" llx="-40" lly="178" urx="477" ury="269"/> + <char name="equal" width="570" llx="33" lly="107" urx="537" ury="399"/> + <char name="eth" width="500" llx="-3" lly="-13" urx="454" ury="699"/> + <char name="exclam" width="389" llx="67" lly="-13" urx="370" ury="684"/> + <char name="exclamdown" width="389" llx="19" lly="-205" urx="322" ury="492"/> + <char name="f" width="333" llx="-169" lly="-205" urx="446" ury="698"/> + <char name="fi" width="556" llx="-188" lly="-205" urx="514" ury="703"/> + <char name="five" width="500" llx="-11" lly="-13" urx="487" ury="669"/> + <char name="fl" width="556" llx="-186" lly="-205" urx="553" ury="704"/> + <char name="florin" width="500" llx="-87" lly="-156" urx="537" ury="707"/> + <char name="four" width="500" llx="-15" lly="0" urx="503" ury="683"/> + <char name="fraction" width="167" llx="-169" lly="-14" urx="324" ury="683"/> + <char name="g" width="500" llx="-52" lly="-203" urx="478" ury="462"/> + <char name="germandbls" width="500" llx="-200" lly="-200" urx="473" ury="705"/> + <char name="grave" width="333" llx="85" lly="516" urx="297" ury="697"/> + <char name="greater" width="570" llx="31" lly="-8" urx="539" ury="514"/> + <char name="guillemotleft" width="500" llx="12" lly="32" urx="468" ury="415"/> + <char name="guillemotright" width="500" llx="12" lly="32" urx="468" ury="415"/> + <char name="guilsinglleft" width="333" llx="32" lly="32" urx="303" ury="415"/> + <char name="guilsinglright" width="333" llx="10" lly="32" urx="281" ury="415"/> + <char name="h" width="556" llx="-13" lly="-9" urx="498" ury="699"/> + <char name="hungarumlaut" width="333" llx="69" lly="516" urx="498" ury="697"/> + <char name="hyphen" width="333" llx="2" lly="166" urx="271" ury="282"/> + <char name="i" width="278" llx="2" lly="-9" urx="263" ury="684"/> + <char name="iacute" width="278" llx="2" lly="-9" urx="352" ury="697"/> + <char name="icircumflex" width="278" llx="-3" lly="-9" urx="324" ury="690"/> + <char name="idieresis" width="278" llx="2" lly="-9" urx="364" ury="655"/> + <char name="igrave" width="278" llx="2" lly="-9" urx="259" ury="697"/> + <char name="j" width="278" llx="-189" lly="-207" urx="279" ury="684"/> + <char name="k" width="500" llx="-23" lly="-8" urx="483" ury="699"/> + <char name="l" width="278" llx="2" lly="-9" urx="290" ury="699"/> + <char name="less" width="570" llx="31" lly="-8" urx="539" ury="514"/> + <char name="logicalnot" width="606" llx="51" lly="108" urx="555" ury="399"/> + <char name="lslash" width="278" llx="-7" lly="-9" urx="307" ury="699"/> + <char name="m" width="778" llx="-14" lly="-9" urx="722" ury="462"/> + <char name="macron" width="333" llx="51" lly="553" urx="393" ury="623"/> + <char name="minus" width="330" llx="51" lly="209" urx="555" ury="297"/> + <char name="mu" width="576" llx="-60" lly="-207" urx="516" ury="449"/> + <char name="multiply" width="570" llx="48" lly="16" urx="522" ury="490"/> + <char name="n" width="556" llx="-6" lly="-9" urx="493" ury="462"/> + <char name="nine" width="500" llx="-12" lly="-10" urx="475" ury="683"/> + <char name="ntilde" width="556" llx="-6" lly="-9" urx="504" ury="655"/> + <char name="numbersign" width="500" llx="-33" lly="0" urx="533" ury="700"/> + <char name="o" width="500" llx="-3" lly="-13" urx="441" ury="462"/> + <char name="oacute" width="500" llx="-3" lly="-13" urx="463" ury="697"/> + <char name="ocircumflex" width="500" llx="-3" lly="-13" urx="451" ury="690"/> + <char name="odieresis" width="500" llx="-3" lly="-13" urx="471" ury="655"/> + <char name="oe" width="722" llx="6" lly="-13" urx="674" ury="462"/> + <char name="ogonek" width="333" llx="15" lly="-183" urx="244" ury="34"/> + <char name="ograve" width="500" llx="-3" lly="-13" urx="441" ury="697"/> + <char name="one" width="500" llx="5" lly="0" urx="419" ury="683"/> + <char name="onehalf" width="750" llx="-9" lly="-14" urx="723" ury="683"/> + <char name="onequarter" width="750" llx="7" lly="-14" urx="721" ury="683"/> + <char name="onesuperior" width="300" llx="30" lly="274" urx="301" ury="683"/> + <char name="ordfeminine" width="266" llx="16" lly="399" urx="330" ury="685"/> + <char name="ordmasculine" width="300" llx="56" lly="400" urx="347" ury="685"/> + <char name="oslash" width="500" llx="-3" lly="-119" urx="441" ury="560"/> + <char name="otilde" width="500" llx="-3" lly="-13" urx="491" ury="655"/> + <char name="p" width="500" llx="-120" lly="-205" urx="446" ury="462"/> + <char name="paragraph" width="500" llx="-57" lly="-193" urx="562" ury="669"/> + <char name="parenleft" width="333" llx="28" lly="-179" urx="344" ury="685"/> + <char name="parenright" width="333" llx="-44" lly="-179" urx="271" ury="685"/> + <char name="percent" width="833" llx="39" lly="-10" urx="793" ury="692"/> + <char name="period" width="250" llx="-9" lly="-13" urx="139" ury="135"/> + <char name="periodcentered" width="250" llx="51" lly="257" urx="199" ury="405"/> + <char name="perthousand" width="1000" llx="7" lly="-29" urx="996" ury="706"/> + <char name="plus" width="570" llx="33" lly="0" urx="537" ury="506"/> + <char name="plusminus" width="570" llx="33" lly="0" urx="537" ury="506"/> + <char name="q" width="500" llx="1" lly="-205" urx="471" ury="462"/> + <char name="question" width="500" llx="79" lly="-13" urx="470" ury="684"/> + <char name="questiondown" width="500" llx="30" lly="-205" urx="421" ury="492"/> + <char name="quotedbl" width="555" llx="136" lly="398" urx="536" ury="685"/> + <char name="quotedblbase" width="500" llx="-57" lly="-182" urx="403" ury="134"/> + <char name="quotedblleft" width="500" llx="53" lly="369" urx="513" ury="685"/> + <char name="quotedblright" width="500" llx="53" lly="369" urx="513" ury="685"/> + <char name="quoteleft" width="333" llx="128" lly="369" urx="332" ury="685"/> + <char name="quoteright" width="333" llx="98" lly="369" urx="302" ury="685"/> + <char name="quotesinglbase" width="333" llx="-5" lly="-182" urx="199" ury="134"/> + <char name="quotesingle" width="278" llx="128" lly="398" urx="268" ury="685"/> + <char name="r" width="389" llx="-21" lly="0" urx="389" ury="462"/> + <char name="registered" width="747" llx="30" lly="-18" urx="718" ury="685"/> + <char name="ring" width="333" llx="127" lly="516" urx="340" ury="729"/> + <char name="s" width="389" llx="-19" lly="-13" urx="333" ury="462"/> + <char name="scaron" width="389" llx="-19" lly="-13" urx="424" ury="690"/> + <char name="section" width="500" llx="36" lly="-143" urx="459" ury="685"/> + <char name="semicolon" width="333" llx="-25" lly="-183" urx="264" ury="459"/> + <char name="seven" width="500" llx="52" lly="0" urx="525" ury="669"/> + <char name="six" width="500" llx="23" lly="-15" urx="509" ury="679"/> + <char name="slash" width="278" llx="-64" lly="-18" urx="342" ury="685"/> + <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="250"/> - <char name="sterling" width="500"/> - <char name="t" width="278"/> - <char name="thorn" width="500"/> - <char name="three" width="500"/> - <char name="threequarters" width="750"/> - <char name="threesuperior" width="300"/> - <char name="tilde" width="333"/> - <char name="trademark" width="1000"/> - <char name="two" width="500"/> - <char name="twosuperior" width="300"/> - <char name="u" width="556"/> - <char name="uacute" width="556"/> - <char name="ucircumflex" width="556"/> - <char name="udieresis" width="556"/> - <char name="ugrave" width="556"/> - <char name="underscore" width="500"/> - <char name="v" width="444"/> - <char name="w" width="667"/> - <char name="x" width="500"/> - <char name="y" width="444"/> - <char name="yacute" width="444"/> - <char name="ydieresis" width="444"/> - <char name="yen" width="500"/> - <char name="z" width="389"/> - <char name="zcaron" width="389"/> - <char name="zero" width="500"/> - </widths> + <char name="sterling" width="500" llx="-32" lly="-12" urx="510" ury="683"/> + <char name="t" width="278" llx="-11" lly="-9" urx="281" ury="594"/> + <char name="thorn" width="500" llx="-120" lly="-205" urx="446" ury="699"/> + <char name="three" width="500" llx="-15" lly="-13" urx="450" ury="683"/> + <char name="threequarters" width="750" llx="7" lly="-14" urx="726" ury="683"/> + <char name="threesuperior" width="300" llx="17" lly="265" urx="321" ury="683"/> + <char name="tilde" width="333" llx="48" lly="536" urx="407" ury="655"/> + <char name="trademark" width="1000" llx="32" lly="263" urx="968" ury="669"/> + <char name="two" width="500" llx="-27" lly="0" urx="446" ury="683"/> + <char name="twosuperior" width="300" llx="2" lly="274" urx="313" ury="683"/> + <char name="u" width="556" llx="15" lly="-9" urx="492" ury="462"/> + <char name="uacute" width="556" llx="15" lly="-9" urx="492" ury="697"/> + <char name="ucircumflex" width="556" llx="15" lly="-9" urx="492" ury="690"/> + <char name="udieresis" width="556" llx="15" lly="-9" urx="499" ury="655"/> + <char name="ugrave" width="556" llx="15" lly="-9" urx="492" ury="697"/> + <char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/> + <char name="v" width="444" llx="16" lly="-13" urx="401" ury="462"/> + <char name="w" width="667" llx="16" lly="-13" urx="614" ury="462"/> + <char name="x" width="500" llx="-46" lly="-13" urx="469" ury="462"/> + <char name="y" width="444" llx="-94" lly="-205" urx="392" ury="462"/> + <char name="yacute" width="444" llx="-94" lly="-205" urx="435" ury="697"/> + <char name="ydieresis" width="444" llx="-94" lly="-205" urx="443" ury="655"/> + <char name="yen" width="500" llx="33" lly="0" urx="628" ury="669"/> + <char name="z" width="389" llx="-43" lly="-78" urx="368" ury="449"/> + <char name="zcaron" width="389" llx="-43" lly="-78" urx="424" ury="690"/> + <char name="zero" width="500" llx="17" lly="-14" urx="477" ury="683"/> + </char-metrics> <kerning kpx1="79"> <pair kern="-40" kpx2="65"/> <pair kern="-50" kpx2="87"/> diff --git a/src/codegen/fonts/TimesItalic.xml b/src/codegen/fonts/TimesItalic.xml index 514aaa6dd..607f4d701 100644 --- a/src/codegen/fonts/TimesItalic.xml +++ b/src/codegen/fonts/TimesItalic.xml @@ -22,245 +22,246 @@ <family-name>Times</family-name> <class-name>TimesItalic</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>653</cap-height> <x-height>441</x-height> <ascender>683</ascender> <descender>-205</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="611"/> - <char name="AE" width="889"/> - <char name="Aacute" width="611"/> - <char name="Acircumflex" width="611"/> - <char name="Adieresis" width="611"/> - <char name="Agrave" width="611"/> - <char name="Aring" width="611"/> - <char name="Atilde" width="611"/> - <char name="B" width="611"/> - <char name="C" width="667"/> - <char name="Ccedilla" width="667"/> - <char name="D" width="722"/> - <char name="E" width="611"/> - <char name="Eacute" width="611"/> - <char name="Ecircumflex" width="611"/> - <char name="Edieresis" width="611"/> - <char name="Egrave" width="611"/> - <char name="Eth" width="722"/> - <char name="Euro" width="500"/> - <char name="F" width="611"/> - <char name="G" width="722"/> - <char name="H" width="722"/> - <char name="I" width="333"/> - <char name="Iacute" width="333"/> - <char name="Icircumflex" width="333"/> - <char name="Idieresis" width="333"/> - <char name="Igrave" width="333"/> - <char name="J" width="444"/> - <char name="K" width="667"/> - <char name="L" width="556"/> - <char name="Lslash" width="556"/> - <char name="M" width="833"/> - <char name="N" width="667"/> - <char name="Ntilde" width="667"/> - <char name="O" width="722"/> - <char name="OE" width="944"/> - <char name="Oacute" width="722"/> - <char name="Ocircumflex" width="722"/> - <char name="Odieresis" width="722"/> - <char name="Ograve" width="722"/> - <char name="Oslash" width="722"/> - <char name="Otilde" width="722"/> - <char name="P" width="611"/> - <char name="Q" width="722"/> - <char name="R" width="611"/> - <char name="S" width="500"/> - <char name="Scaron" width="500"/> - <char name="T" width="556"/> - <char name="Thorn" width="611"/> - <char name="U" width="722"/> - <char name="Uacute" width="722"/> - <char name="Ucircumflex" width="722"/> - <char name="Udieresis" width="722"/> - <char name="Ugrave" width="722"/> - <char name="V" width="611"/> - <char name="W" width="833"/> - <char name="X" width="611"/> - <char name="Y" width="556"/> - <char name="Yacute" width="556"/> - <char name="Ydieresis" width="556"/> - <char name="Z" width="556"/> - <char name="Zcaron" width="556"/> - <char name="a" width="500"/> - <char name="aacute" width="500"/> - <char name="acircumflex" width="500"/> - <char name="acute" width="333"/> - <char name="adieresis" width="500"/> - <char name="ae" width="667"/> - <char name="agrave" width="500"/> - <char name="ampersand" width="778"/> - <char name="aring" width="500"/> - <char name="asciicircum" width="422"/> - <char name="asciitilde" width="541"/> - <char name="asterisk" width="500"/> - <char name="at" width="920"/> - <char name="atilde" width="500"/> - <char name="b" width="500"/> - <char name="backslash" width="278"/> - <char name="bar" width="275"/> - <char name="braceleft" width="400"/> - <char name="braceright" width="400"/> - <char name="bracketleft" width="389"/> - <char name="bracketright" width="389"/> - <char name="breve" width="333"/> - <char name="brokenbar" width="275"/> - <char name="bullet" width="350"/> - <char name="c" width="444"/> - <char name="caron" width="333"/> - <char name="ccedilla" width="444"/> - <char name="cedilla" width="333"/> - <char name="cent" width="500"/> - <char name="circumflex" width="333"/> - <char name="colon" width="333"/> - <char name="comma" width="250"/> - <char name="copyright" width="760"/> - <char name="currency" width="500"/> - <char name="d" width="500"/> - <char name="dagger" width="500"/> - <char name="daggerdbl" width="500"/> - <char name="degree" width="400"/> - <char name="dieresis" width="333"/> - <char name="divide" width="675"/> - <char name="dollar" width="500"/> - <char name="dotaccent" width="333"/> - <char name="dotlessi" width="278"/> - <char name="e" width="444"/> - <char name="eacute" width="444"/> - <char name="ecircumflex" width="444"/> - <char name="edieresis" width="444"/> - <char name="egrave" width="444"/> - <char name="eight" width="500"/> - <char name="ellipsis" width="889"/> - <char name="emdash" width="889"/> - <char name="endash" width="500"/> - <char name="equal" width="675"/> - <char name="eth" width="500"/> - <char name="exclam" width="333"/> - <char name="exclamdown" width="389"/> - <char name="f" width="278"/> - <char name="fi" width="500"/> - <char name="five" width="500"/> - <char name="fl" width="500"/> - <char name="florin" width="500"/> - <char name="four" width="500"/> - <char name="fraction" width="167"/> - <char name="g" width="500"/> - <char name="germandbls" width="500"/> - <char name="grave" width="333"/> - <char name="greater" width="675"/> - <char name="guillemotleft" width="500"/> - <char name="guillemotright" width="500"/> - <char name="guilsinglleft" width="333"/> - <char name="guilsinglright" width="333"/> - <char name="h" width="500"/> - <char name="hungarumlaut" width="333"/> - <char name="hyphen" width="333"/> - <char name="i" width="278"/> - <char name="iacute" width="278"/> - <char name="icircumflex" width="278"/> - <char name="idieresis" width="278"/> - <char name="igrave" width="278"/> - <char name="j" width="278"/> - <char name="k" width="444"/> - <char name="l" width="278"/> - <char name="less" width="675"/> - <char name="logicalnot" width="675"/> - <char name="lslash" width="278"/> - <char name="m" width="722"/> - <char name="macron" width="333"/> - <char name="minus" width="675"/> - <char name="mu" width="500"/> - <char name="multiply" width="675"/> - <char name="n" width="500"/> - <char name="nine" width="500"/> - <char name="ntilde" width="500"/> - <char name="numbersign" width="500"/> - <char name="o" width="500"/> - <char name="oacute" width="500"/> - <char name="ocircumflex" width="500"/> - <char name="odieresis" width="500"/> - <char name="oe" width="667"/> - <char name="ogonek" width="333"/> - <char name="ograve" width="500"/> - <char name="one" width="500"/> - <char name="onehalf" width="750"/> - <char name="onequarter" width="750"/> - <char name="onesuperior" width="300"/> - <char name="ordfeminine" width="276"/> - <char name="ordmasculine" width="310"/> - <char name="oslash" width="500"/> - <char name="otilde" width="500"/> - <char name="p" width="500"/> - <char name="paragraph" width="523"/> - <char name="parenleft" width="333"/> - <char name="parenright" width="333"/> - <char name="percent" width="833"/> - <char name="period" width="250"/> - <char name="periodcentered" width="250"/> - <char name="perthousand" width="1000"/> - <char name="plus" width="675"/> - <char name="plusminus" width="675"/> - <char name="q" width="500"/> - <char name="question" width="500"/> - <char name="questiondown" width="500"/> - <char name="quotedbl" width="420"/> - <char name="quotedblbase" width="556"/> - <char name="quotedblleft" width="556"/> - <char name="quotedblright" width="556"/> - <char name="quoteleft" width="333"/> - <char name="quoteright" width="333"/> - <char name="quotesinglbase" width="333"/> - <char name="quotesingle" width="214"/> - <char name="r" width="389"/> - <char name="registered" width="760"/> - <char name="ring" width="333"/> - <char name="s" width="389"/> - <char name="scaron" width="389"/> - <char name="section" width="500"/> - <char name="semicolon" width="333"/> - <char name="seven" width="500"/> - <char name="six" width="500"/> - <char name="slash" width="278"/> - <char name="space" width="250"/> + <char-metrics> + <char name="A" width="611" llx="-51" lly="0" urx="564" ury="668"/> + <char name="AE" width="889" llx="-27" lly="0" urx="911" ury="653"/> + <char name="Aacute" width="611" llx="-51" lly="0" urx="564" ury="876"/> + <char name="Acircumflex" width="611" llx="-51" lly="0" urx="564" ury="873"/> + <char name="Adieresis" width="611" llx="-51" lly="0" urx="564" ury="818"/> + <char name="Agrave" width="611" llx="-51" lly="0" urx="564" ury="876"/> + <char name="Aring" width="611" llx="-51" lly="0" urx="564" ury="883"/> + <char name="Atilde" width="611" llx="-51" lly="0" urx="566" ury="836"/> + <char name="B" width="611" llx="-8" lly="0" urx="588" ury="653"/> + <char name="C" width="667" llx="66" lly="-18" urx="689" ury="666"/> + <char name="Ccedilla" width="667" llx="66" lly="-217" urx="689" ury="666"/> + <char name="D" width="722" llx="-8" lly="0" urx="700" ury="653"/> + <char name="E" width="611" llx="-1" lly="0" urx="634" ury="653"/> + <char name="Eacute" width="611" llx="-1" lly="0" urx="634" ury="876"/> + <char name="Ecircumflex" width="611" llx="-1" lly="0" urx="634" ury="873"/> + <char name="Edieresis" width="611" llx="-1" lly="0" urx="634" ury="818"/> + <char name="Egrave" width="611" llx="-1" lly="0" urx="634" ury="876"/> + <char name="Eth" width="722" llx="-8" lly="0" urx="700" ury="653"/> + <char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="611" llx="8" lly="0" urx="645" ury="653"/> + <char name="G" width="722" llx="52" lly="-18" urx="722" ury="666"/> + <char name="H" width="722" llx="-8" lly="0" urx="767" ury="653"/> + <char name="I" width="333" llx="-8" lly="0" urx="384" ury="653"/> + <char name="Iacute" width="333" llx="-8" lly="0" urx="433" ury="876"/> + <char name="Icircumflex" width="333" llx="-8" lly="0" urx="425" ury="873"/> + <char name="Idieresis" width="333" llx="-8" lly="0" urx="435" ury="818"/> + <char name="Igrave" width="333" llx="-8" lly="0" urx="384" ury="876"/> + <char name="J" width="444" llx="-6" lly="-18" urx="491" ury="653"/> + <char name="K" width="667" llx="7" lly="0" urx="722" ury="653"/> + <char name="L" width="556" llx="-8" lly="0" urx="559" ury="653"/> + <char name="Lslash" width="556" llx="-8" lly="0" urx="559" ury="653"/> + <char name="M" width="833" llx="-18" lly="0" urx="873" ury="653"/> + <char name="N" width="667" llx="-20" lly="-15" urx="727" ury="653"/> + <char name="Ntilde" width="667" llx="-20" lly="-15" urx="727" ury="836"/> + <char name="O" width="722" llx="60" lly="-18" urx="699" ury="666"/> + <char name="OE" width="944" llx="49" lly="-8" urx="964" ury="666"/> + <char name="Oacute" width="722" llx="60" lly="-18" urx="699" ury="876"/> + <char name="Ocircumflex" width="722" llx="60" lly="-18" urx="699" ury="873"/> + <char name="Odieresis" width="722" llx="60" lly="-18" urx="699" ury="818"/> + <char name="Ograve" width="722" llx="60" lly="-18" urx="699" ury="876"/> + <char name="Oslash" width="722" llx="60" lly="-105" urx="699" ury="722"/> + <char name="Otilde" width="722" llx="60" lly="-18" urx="699" ury="836"/> + <char name="P" width="611" llx="0" lly="0" urx="605" ury="653"/> + <char name="Q" width="722" llx="59" lly="-182" urx="699" ury="666"/> + <char name="R" width="611" llx="-13" lly="0" urx="588" ury="653"/> + <char name="S" width="500" llx="17" lly="-18" urx="508" ury="667"/> + <char name="Scaron" width="500" llx="17" lly="-18" urx="520" ury="873"/> + <char name="T" width="556" llx="59" lly="0" urx="633" ury="653"/> + <char name="Thorn" width="611" llx="0" lly="0" urx="569" ury="653"/> + <char name="U" width="722" llx="102" lly="-18" urx="765" ury="653"/> + <char name="Uacute" width="722" llx="102" lly="-18" urx="765" ury="876"/> + <char name="Ucircumflex" width="722" llx="102" lly="-18" urx="765" ury="873"/> + <char name="Udieresis" width="722" llx="102" lly="-18" urx="765" ury="818"/> + <char name="Ugrave" width="722" llx="102" lly="-18" urx="765" ury="876"/> + <char name="V" width="611" llx="76" lly="-18" urx="688" ury="653"/> + <char name="W" width="833" llx="71" lly="-18" urx="906" ury="653"/> + <char name="X" width="611" llx="-29" lly="0" urx="655" ury="653"/> + <char name="Y" width="556" llx="78" lly="0" urx="633" ury="653"/> + <char name="Yacute" width="556" llx="78" lly="0" urx="633" ury="876"/> + <char name="Ydieresis" width="556" llx="78" lly="0" urx="633" ury="818"/> + <char name="Z" width="556" llx="-6" lly="0" urx="606" ury="653"/> + <char name="Zcaron" width="556" llx="-6" lly="0" urx="606" ury="873"/> + <char name="a" width="500" llx="17" lly="-11" urx="476" ury="441"/> + <char name="aacute" width="500" llx="17" lly="-11" urx="487" ury="664"/> + <char name="acircumflex" width="500" llx="17" lly="-11" urx="476" ury="661"/> + <char name="acute" width="333" llx="180" lly="494" urx="403" ury="664"/> + <char name="adieresis" width="500" llx="17" lly="-11" urx="489" ury="606"/> + <char name="ae" width="667" llx="23" lly="-11" urx="640" ury="441"/> + <char name="agrave" width="500" llx="17" lly="-11" urx="476" ury="664"/> + <char name="ampersand" width="778" llx="76" lly="-18" urx="723" ury="666"/> + <char name="aring" width="500" llx="17" lly="-11" urx="476" ury="691"/> + <char name="asciicircum" width="422" llx="0" lly="301" urx="422" ury="666"/> + <char name="asciitilde" width="541" llx="40" lly="183" urx="502" ury="323"/> + <char name="asterisk" width="500" llx="128" lly="255" urx="492" ury="666"/> + <char name="at" width="920" llx="118" lly="-18" urx="806" ury="666"/> + <char name="atilde" width="500" llx="17" lly="-11" urx="511" ury="624"/> + <char name="b" width="500" llx="23" lly="-11" urx="473" ury="683"/> + <char name="backslash" width="278" llx="-41" lly="-18" urx="319" ury="666"/> + <char name="bar" width="275" llx="105" lly="-217" urx="171" ury="783"/> + <char name="braceleft" width="400" llx="51" lly="-177" urx="407" ury="687"/> + <char name="braceright" width="400" llx="-7" lly="-177" urx="349" ury="687"/> + <char name="bracketleft" width="389" llx="21" lly="-153" urx="391" ury="663"/> + <char name="bracketright" width="389" llx="12" lly="-153" urx="382" ury="663"/> + <char name="breve" width="333" llx="117" lly="492" urx="418" ury="650"/> + <char name="brokenbar" width="275" llx="105" lly="-142" urx="171" ury="708"/> + <char name="bullet" width="350" llx="40" lly="191" urx="310" ury="461"/> + <char name="c" width="444" llx="30" lly="-11" urx="425" ury="441"/> + <char name="caron" width="333" llx="121" lly="492" urx="426" ury="661"/> + <char name="ccedilla" width="444" llx="30" lly="-217" urx="425" ury="441"/> + <char name="cedilla" width="333" llx="-30" lly="-217" urx="182" ury="0"/> + <char name="cent" width="500" llx="77" lly="-143" urx="472" ury="560"/> + <char name="circumflex" width="333" llx="91" lly="492" urx="385" ury="661"/> + <char name="colon" width="333" llx="50" lly="-11" urx="261" ury="441"/> + <char name="comma" width="250" llx="-4" lly="-129" urx="135" ury="101"/> + <char name="copyright" width="760" llx="41" lly="-18" urx="719" ury="666"/> + <char name="currency" width="500" llx="-22" lly="53" urx="522" ury="597"/> + <char name="d" width="500" llx="15" lly="-13" urx="527" ury="683"/> + <char name="dagger" width="500" llx="101" lly="-159" urx="488" ury="666"/> + <char name="daggerdbl" width="500" llx="22" lly="-143" urx="491" ury="666"/> + <char name="degree" width="400" llx="101" lly="390" urx="387" ury="676"/> + <char name="dieresis" width="333" llx="107" lly="548" urx="405" ury="646"/> + <char name="divide" width="675" llx="86" lly="-11" urx="590" ury="517"/> + <char name="dollar" width="500" llx="31" lly="-89" urx="497" ury="731"/> + <char name="dotaccent" width="333" llx="207" lly="548" urx="305" ury="646"/> + <char name="dotlessi" width="278" llx="49" lly="-11" urx="235" ury="441"/> + <char name="e" width="444" llx="31" lly="-11" urx="412" ury="441"/> + <char name="eacute" width="444" llx="31" lly="-11" urx="459" ury="664"/> + <char name="ecircumflex" width="444" llx="31" lly="-11" urx="441" ury="661"/> + <char name="edieresis" width="444" llx="31" lly="-11" urx="451" ury="606"/> + <char name="egrave" width="444" llx="31" lly="-11" urx="412" ury="664"/> + <char name="eight" width="500" llx="30" lly="-7" urx="493" ury="676"/> + <char name="ellipsis" width="889" llx="57" lly="-11" urx="762" ury="100"/> + <char name="emdash" width="889" llx="-6" lly="197" urx="894" ury="243"/> + <char name="endash" width="500" llx="-6" lly="197" urx="505" ury="243"/> + <char name="equal" width="675" llx="86" lly="120" urx="590" ury="386"/> + <char name="eth" width="500" llx="27" lly="-11" urx="482" ury="683"/> + <char name="exclam" width="333" llx="39" lly="-11" urx="302" ury="667"/> + <char name="exclamdown" width="389" llx="59" lly="-205" urx="322" ury="473"/> + <char name="f" width="278" llx="-147" lly="-207" urx="424" ury="678"/> + <char name="fi" width="500" llx="-141" lly="-207" urx="481" ury="681"/> + <char name="five" width="500" llx="15" lly="-7" urx="491" ury="666"/> + <char name="fl" width="500" llx="-141" lly="-204" urx="518" ury="682"/> + <char name="florin" width="500" llx="25" lly="-182" urx="507" ury="682"/> + <char name="four" width="500" llx="1" lly="0" urx="479" ury="676"/> + <char name="fraction" width="167" llx="-169" lly="-10" urx="337" ury="676"/> + <char name="g" width="500" llx="8" lly="-206" urx="472" ury="441"/> + <char name="germandbls" width="500" llx="-168" lly="-207" urx="493" ury="679"/> + <char name="grave" width="333" llx="121" lly="492" urx="311" ury="664"/> + <char name="greater" width="675" llx="84" lly="-8" urx="592" ury="514"/> + <char name="guillemotleft" width="500" llx="53" lly="37" urx="445" ury="403"/> + <char name="guillemotright" width="500" llx="55" lly="37" urx="447" ury="403"/> + <char name="guilsinglleft" width="333" llx="51" lly="37" urx="281" ury="403"/> + <char name="guilsinglright" width="333" llx="52" lly="37" urx="282" ury="403"/> + <char name="h" width="500" llx="19" lly="-9" urx="478" ury="683"/> + <char name="hungarumlaut" width="333" llx="93" lly="494" urx="486" ury="664"/> + <char name="hyphen" width="333" llx="49" lly="192" urx="282" ury="255"/> + <char name="i" width="278" llx="49" lly="-11" urx="264" ury="654"/> + <char name="iacute" width="278" llx="49" lly="-11" urx="355" ury="664"/> + <char name="icircumflex" width="278" llx="33" lly="-11" urx="327" ury="661"/> + <char name="idieresis" width="278" llx="49" lly="-11" urx="352" ury="606"/> + <char name="igrave" width="278" llx="49" lly="-11" urx="284" ury="664"/> + <char name="j" width="278" llx="-124" lly="-207" urx="276" ury="654"/> + <char name="k" width="444" llx="14" lly="-11" urx="461" ury="683"/> + <char name="l" width="278" llx="41" lly="-11" urx="279" ury="683"/> + <char name="less" width="675" llx="84" lly="-8" urx="592" ury="514"/> + <char name="logicalnot" width="675" llx="86" lly="108" urx="590" ury="386"/> + <char name="lslash" width="278" llx="41" lly="-11" urx="312" ury="683"/> + <char name="m" width="722" llx="12" lly="-9" urx="704" ury="441"/> + <char name="macron" width="333" llx="99" lly="532" urx="411" ury="583"/> + <char name="minus" width="675" llx="86" lly="220" urx="590" ury="286"/> + <char name="mu" width="500" llx="-30" lly="-209" urx="497" ury="428"/> + <char name="multiply" width="675" llx="93" lly="8" urx="582" ury="497"/> + <char name="n" width="500" llx="14" lly="-9" urx="474" ury="441"/> + <char name="nine" width="500" llx="23" lly="-17" urx="492" ury="676"/> + <char name="ntilde" width="500" llx="14" lly="-9" urx="476" ury="624"/> + <char name="numbersign" width="500" llx="2" lly="0" urx="540" ury="676"/> + <char name="o" width="500" llx="27" lly="-11" urx="468" ury="441"/> + <char name="oacute" width="500" llx="27" lly="-11" urx="487" ury="664"/> + <char name="ocircumflex" width="500" llx="27" lly="-11" urx="468" ury="661"/> + <char name="odieresis" width="500" llx="27" lly="-11" urx="489" ury="606"/> + <char name="oe" width="667" llx="20" lly="-12" urx="646" ury="441"/> + <char name="ogonek" width="333" llx="20" lly="-169" urx="203" ury="40"/> + <char name="ograve" width="500" llx="27" lly="-11" urx="468" ury="664"/> + <char name="one" width="500" llx="49" lly="0" urx="409" ury="676"/> + <char name="onehalf" width="750" llx="34" lly="-10" urx="749" ury="676"/> + <char name="onequarter" width="750" llx="33" lly="-10" urx="736" ury="676"/> + <char name="onesuperior" width="300" llx="43" lly="271" urx="284" ury="676"/> + <char name="ordfeminine" width="276" llx="42" lly="406" urx="352" ury="676"/> + <char name="ordmasculine" width="310" llx="67" lly="406" urx="362" ury="676"/> + <char name="oslash" width="500" llx="28" lly="-135" urx="469" ury="554"/> + <char name="otilde" width="500" llx="27" lly="-11" urx="496" ury="624"/> + <char name="p" width="500" llx="-75" lly="-205" urx="469" ury="441"/> + <char name="paragraph" width="523" llx="55" lly="-123" urx="616" ury="653"/> + <char name="parenleft" width="333" llx="42" lly="-181" urx="315" ury="669"/> + <char name="parenright" width="333" llx="16" lly="-180" urx="289" ury="669"/> + <char name="percent" width="833" llx="79" lly="-13" urx="790" ury="676"/> + <char name="period" width="250" llx="27" lly="-11" urx="138" ury="100"/> + <char name="periodcentered" width="250" llx="70" lly="199" urx="181" ury="310"/> + <char name="perthousand" width="1000" llx="25" lly="-19" urx="1010" ury="706"/> + <char name="plus" width="675" llx="86" lly="0" urx="590" ury="506"/> + <char name="plusminus" width="675" llx="86" lly="0" urx="590" ury="506"/> + <char name="q" width="500" llx="25" lly="-209" urx="483" ury="441"/> + <char name="question" width="500" llx="132" lly="-12" urx="472" ury="664"/> + <char name="questiondown" width="500" llx="28" lly="-205" urx="368" ury="471"/> + <char name="quotedbl" width="420" llx="144" lly="421" urx="432" ury="666"/> + <char name="quotedblbase" width="556" llx="57" lly="-129" urx="405" ury="101"/> + <char name="quotedblleft" width="556" llx="166" lly="436" urx="514" ury="666"/> + <char name="quotedblright" width="556" llx="151" lly="436" urx="499" ury="666"/> + <char name="quoteleft" width="333" llx="171" lly="436" urx="310" ury="666"/> + <char name="quoteright" width="333" llx="151" lly="436" urx="290" ury="666"/> + <char name="quotesinglbase" width="333" llx="44" lly="-129" urx="183" ury="101"/> + <char name="quotesingle" width="214" llx="132" lly="421" urx="241" ury="666"/> + <char name="r" width="389" llx="45" lly="0" urx="412" ury="441"/> + <char name="registered" width="760" llx="41" lly="-18" urx="719" ury="666"/> + <char name="ring" width="333" llx="155" lly="492" urx="355" ury="691"/> + <char name="s" width="389" llx="16" lly="-13" urx="366" ury="442"/> + <char name="scaron" width="389" llx="16" lly="-13" urx="454" ury="661"/> + <char name="section" width="500" llx="53" lly="-162" urx="461" ury="666"/> + <char name="semicolon" width="333" llx="27" lly="-129" urx="261" ury="441"/> + <char name="seven" width="500" llx="75" lly="-8" urx="537" ury="666"/> + <char name="six" width="500" llx="30" lly="-7" urx="521" ury="686"/> + <char name="slash" width="278" llx="-65" lly="-18" urx="386" ury="666"/> + <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="250"/> - <char name="sterling" width="500"/> - <char name="t" width="278"/> - <char name="thorn" width="500"/> - <char name="three" width="500"/> - <char name="threequarters" width="750"/> - <char name="threesuperior" width="300"/> - <char name="tilde" width="333"/> - <char name="trademark" width="980"/> - <char name="two" width="500"/> - <char name="twosuperior" width="300"/> - <char name="u" width="500"/> - <char name="uacute" width="500"/> - <char name="ucircumflex" width="500"/> - <char name="udieresis" width="500"/> - <char name="ugrave" width="500"/> - <char name="underscore" width="500"/> - <char name="v" width="444"/> - <char name="w" width="667"/> - <char name="x" width="444"/> - <char name="y" width="444"/> - <char name="yacute" width="444"/> - <char name="ydieresis" width="444"/> - <char name="yen" width="500"/> - <char name="z" width="389"/> - <char name="zcaron" width="389"/> - <char name="zero" width="500"/> - </widths> + <char name="sterling" width="500" llx="10" lly="-6" urx="517" ury="670"/> + <char name="t" width="278" llx="37" lly="-11" urx="296" ury="546"/> + <char name="thorn" width="500" llx="-75" lly="-205" urx="469" ury="683"/> + <char name="three" width="500" llx="15" lly="-7" urx="465" ury="676"/> + <char name="threequarters" width="750" llx="23" lly="-10" urx="736" ury="676"/> + <char name="threesuperior" width="300" llx="43" lly="268" urx="339" ury="676"/> + <char name="tilde" width="333" llx="100" lly="517" urx="427" ury="624"/> + <char name="trademark" width="980" llx="30" lly="247" urx="957" ury="653"/> + <char name="two" width="500" llx="12" lly="0" urx="452" ury="676"/> + <char name="twosuperior" width="300" llx="33" lly="271" urx="324" ury="676"/> + <char name="u" width="500" llx="42" lly="-11" urx="475" ury="441"/> + <char name="uacute" width="500" llx="42" lly="-11" urx="477" ury="664"/> + <char name="ucircumflex" width="500" llx="42" lly="-11" urx="475" ury="661"/> + <char name="udieresis" width="500" llx="42" lly="-11" urx="479" ury="606"/> + <char name="ugrave" width="500" llx="42" lly="-11" urx="475" ury="664"/> + <char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/> + <char name="v" width="444" llx="21" lly="-18" urx="426" ury="441"/> + <char name="w" width="667" llx="16" lly="-18" urx="648" ury="441"/> + <char name="x" width="444" llx="-27" lly="-11" urx="447" ury="441"/> + <char name="y" width="444" llx="-24" lly="-206" urx="426" ury="441"/> + <char name="yacute" width="444" llx="-24" lly="-206" urx="459" ury="664"/> + <char name="ydieresis" width="444" llx="-24" lly="-206" urx="441" ury="606"/> + <char name="yen" width="500" llx="27" lly="0" urx="603" ury="653"/> + <char name="z" width="389" llx="-2" lly="-81" urx="380" ury="428"/> + <char name="zcaron" width="389" llx="-2" lly="-81" urx="434" ury="661"/> + <char name="zero" width="500" llx="32" lly="-7" urx="497" ury="676"/> + </char-metrics> <kerning kpx1="79"> <pair kern="-55" kpx2="65"/> <pair kern="-50" kpx2="87"/> @@ -641,4 +642,4 @@ <pair kern="0" kpx2="121"/> <pair kern="-40" kpx2="118"/> </kerning> -</font-metrics>
\ No newline at end of file +</font-metrics> diff --git a/src/codegen/fonts/TimesRoman.xml b/src/codegen/fonts/TimesRoman.xml index 9ddadfddd..9e16b6a3b 100644 --- a/src/codegen/fonts/TimesRoman.xml +++ b/src/codegen/fonts/TimesRoman.xml @@ -22,245 +22,246 @@ <family-name>Times</family-name> <class-name>TimesRoman</class-name> <encoding>StandardEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>662</cap-height> <x-height>450</x-height> <ascender>683</ascender> <descender>-217</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="A" width="722"/> - <char name="AE" width="889"/> - <char name="Aacute" width="722"/> - <char name="Acircumflex" width="722"/> - <char name="Adieresis" width="722"/> - <char name="Agrave" width="722"/> - <char name="Aring" width="722"/> - <char name="Atilde" width="722"/> - <char name="B" width="667"/> - <char name="C" width="667"/> - <char name="Ccedilla" width="667"/> - <char name="D" width="722"/> - <char name="E" width="611"/> - <char name="Eacute" width="611"/> - <char name="Ecircumflex" width="611"/> - <char name="Edieresis" width="611"/> - <char name="Egrave" width="611"/> - <char name="Eth" width="722"/> - <char name="Euro" width="500"/> - <char name="F" width="556"/> - <char name="G" width="722"/> - <char name="H" width="722"/> - <char name="I" width="333"/> - <char name="Iacute" width="333"/> - <char name="Icircumflex" width="333"/> - <char name="Idieresis" width="333"/> - <char name="Igrave" width="333"/> - <char name="J" width="389"/> - <char name="K" width="722"/> - <char name="L" width="611"/> - <char name="Lslash" width="611"/> - <char name="M" width="889"/> - <char name="N" width="722"/> - <char name="Ntilde" width="722"/> - <char name="O" width="722"/> - <char name="OE" width="889"/> - <char name="Oacute" width="722"/> - <char name="Ocircumflex" width="722"/> - <char name="Odieresis" width="722"/> - <char name="Ograve" width="722"/> - <char name="Oslash" width="722"/> - <char name="Otilde" width="722"/> - <char name="P" width="556"/> - <char name="Q" width="722"/> - <char name="R" width="667"/> - <char name="S" width="556"/> - <char name="Scaron" width="556"/> - <char name="T" width="611"/> - <char name="Thorn" width="556"/> - <char name="U" width="722"/> - <char name="Uacute" width="722"/> - <char name="Ucircumflex" width="722"/> - <char name="Udieresis" width="722"/> - <char name="Ugrave" width="722"/> - <char name="V" width="722"/> - <char name="W" width="944"/> - <char name="X" width="722"/> - <char name="Y" width="722"/> - <char name="Yacute" width="722"/> - <char name="Ydieresis" width="722"/> - <char name="Z" width="611"/> - <char name="Zcaron" width="611"/> - <char name="a" width="444"/> - <char name="aacute" width="444"/> - <char name="acircumflex" width="444"/> - <char name="acute" width="333"/> - <char name="adieresis" width="444"/> - <char name="ae" width="667"/> - <char name="agrave" width="444"/> - <char name="ampersand" width="778"/> - <char name="aring" width="444"/> - <char name="asciicircum" width="469"/> - <char name="asciitilde" width="541"/> - <char name="asterisk" width="500"/> - <char name="at" width="921"/> - <char name="atilde" width="444"/> - <char name="b" width="500"/> - <char name="backslash" width="278"/> - <char name="bar" width="200"/> - <char name="braceleft" width="480"/> - <char name="braceright" width="480"/> - <char name="bracketleft" width="333"/> - <char name="bracketright" width="333"/> - <char name="breve" width="333"/> - <char name="brokenbar" width="200"/> - <char name="bullet" width="350"/> - <char name="c" width="444"/> - <char name="caron" width="333"/> - <char name="ccedilla" width="444"/> - <char name="cedilla" width="333"/> - <char name="cent" width="500"/> - <char name="circumflex" width="333"/> - <char name="colon" width="278"/> - <char name="comma" width="250"/> - <char name="copyright" width="760"/> - <char name="currency" width="500"/> - <char name="d" width="500"/> - <char name="dagger" width="500"/> - <char name="daggerdbl" width="500"/> - <char name="degree" width="400"/> - <char name="dieresis" width="333"/> - <char name="divide" width="564"/> - <char name="dollar" width="500"/> - <char name="dotaccent" width="333"/> - <char name="dotlessi" width="278"/> - <char name="e" width="444"/> - <char name="eacute" width="444"/> - <char name="ecircumflex" width="444"/> - <char name="edieresis" width="444"/> - <char name="egrave" width="444"/> - <char name="eight" width="500"/> - <char name="ellipsis" width="1000"/> - <char name="emdash" width="1000"/> - <char name="endash" width="500"/> - <char name="equal" width="564"/> - <char name="eth" width="500"/> - <char name="exclam" width="333"/> - <char name="exclamdown" width="333"/> - <char name="f" width="333"/> - <char name="fi" width="556"/> - <char name="five" width="500"/> - <char name="fl" width="556"/> - <char name="florin" width="500"/> - <char name="four" width="500"/> - <char name="fraction" width="167"/> - <char name="g" width="500"/> - <char name="germandbls" width="500"/> - <char name="grave" width="333"/> - <char name="greater" width="564"/> - <char name="guillemotleft" width="500"/> - <char name="guillemotright" width="500"/> - <char name="guilsinglleft" width="333"/> - <char name="guilsinglright" width="333"/> - <char name="h" width="500"/> - <char name="hungarumlaut" width="333"/> - <char name="hyphen" width="333"/> - <char name="i" width="278"/> - <char name="iacute" width="278"/> - <char name="icircumflex" width="278"/> - <char name="idieresis" width="278"/> - <char name="igrave" width="278"/> - <char name="j" width="278"/> - <char name="k" width="500"/> - <char name="l" width="278"/> - <char name="less" width="564"/> - <char name="logicalnot" width="564"/> - <char name="lslash" width="278"/> - <char name="m" width="778"/> - <char name="macron" width="333"/> - <char name="minus" width="324"/> - <char name="mu" width="500"/> - <char name="multiply" width="564"/> - <char name="n" width="500"/> - <char name="nine" width="500"/> - <char name="ntilde" width="500"/> - <char name="numbersign" width="500"/> - <char name="o" width="500"/> - <char name="oacute" width="500"/> - <char name="ocircumflex" width="500"/> - <char name="odieresis" width="500"/> - <char name="oe" width="722"/> - <char name="ogonek" width="333"/> - <char name="ograve" width="500"/> - <char name="one" width="500"/> - <char name="onehalf" width="750"/> - <char name="onequarter" width="750"/> - <char name="onesuperior" width="300"/> - <char name="ordfeminine" width="276"/> - <char name="ordmasculine" width="310"/> - <char name="oslash" width="500"/> - <char name="otilde" width="500"/> - <char name="p" width="500"/> - <char name="paragraph" width="453"/> - <char name="parenleft" width="333"/> - <char name="parenright" width="333"/> - <char name="percent" width="833"/> - <char name="period" width="250"/> - <char name="periodcentered" width="250"/> - <char name="perthousand" width="1000"/> - <char name="plus" width="564"/> - <char name="plusminus" width="564"/> - <char name="q" width="500"/> - <char name="question" width="444"/> - <char name="questiondown" width="444"/> - <char name="quotedbl" width="408"/> - <char name="quotedblbase" width="444"/> - <char name="quotedblleft" width="444"/> - <char name="quotedblright" width="444"/> - <char name="quoteleft" width="333"/> - <char name="quoteright" width="333"/> - <char name="quotesinglbase" width="333"/> - <char name="quotesingle" width="180"/> - <char name="r" width="333"/> - <char name="registered" width="760"/> - <char name="ring" width="333"/> - <char name="s" width="389"/> - <char name="scaron" width="389"/> - <char name="section" width="500"/> - <char name="semicolon" width="278"/> - <char name="seven" width="500"/> - <char name="six" width="500"/> - <char name="slash" width="278"/> - <char name="space" width="250"/> + <char-metrics> + <char name="A" width="722" llx="15" lly="0" urx="706" ury="674"/> + <char name="AE" width="889" llx="0" lly="0" urx="863" ury="662"/> + <char name="Aacute" width="722" llx="15" lly="0" urx="706" ury="890"/> + <char name="Acircumflex" width="722" llx="15" lly="0" urx="706" ury="886"/> + <char name="Adieresis" width="722" llx="15" lly="0" urx="706" ury="835"/> + <char name="Agrave" width="722" llx="15" lly="0" urx="706" ury="890"/> + <char name="Aring" width="722" llx="15" lly="0" urx="706" ury="898"/> + <char name="Atilde" width="722" llx="15" lly="0" urx="706" ury="850"/> + <char name="B" width="667" llx="17" lly="0" urx="593" ury="662"/> + <char name="C" width="667" llx="28" lly="-14" urx="633" ury="676"/> + <char name="Ccedilla" width="667" llx="28" lly="-215" urx="633" ury="676"/> + <char name="D" width="722" llx="16" lly="0" urx="685" ury="662"/> + <char name="E" width="611" llx="12" lly="0" urx="597" ury="662"/> + <char name="Eacute" width="611" llx="12" lly="0" urx="597" ury="890"/> + <char name="Ecircumflex" width="611" llx="12" lly="0" urx="597" ury="886"/> + <char name="Edieresis" width="611" llx="12" lly="0" urx="597" ury="835"/> + <char name="Egrave" width="611" llx="12" lly="0" urx="597" ury="890"/> + <char name="Eth" width="722" llx="16" lly="0" urx="685" ury="662"/> + <char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/> + <char name="F" width="556" llx="12" lly="0" urx="546" ury="662"/> + <char name="G" width="722" llx="32" lly="-14" urx="709" ury="676"/> + <char name="H" width="722" llx="19" lly="0" urx="702" ury="662"/> + <char name="I" width="333" llx="18" lly="0" urx="315" ury="662"/> + <char name="Iacute" width="333" llx="18" lly="0" urx="317" ury="890"/> + <char name="Icircumflex" width="333" llx="11" lly="0" urx="322" ury="886"/> + <char name="Idieresis" width="333" llx="18" lly="0" urx="315" ury="835"/> + <char name="Igrave" width="333" llx="18" lly="0" urx="315" ury="890"/> + <char name="J" width="389" llx="10" lly="-14" urx="370" ury="662"/> + <char name="K" width="722" llx="34" lly="0" urx="723" ury="662"/> + <char name="L" width="611" llx="12" lly="0" urx="598" ury="662"/> + <char name="Lslash" width="611" llx="12" lly="0" urx="598" ury="662"/> + <char name="M" width="889" llx="12" lly="0" urx="863" ury="662"/> + <char name="N" width="722" llx="12" lly="-11" urx="707" ury="662"/> + <char name="Ntilde" width="722" llx="12" lly="-11" urx="707" ury="850"/> + <char name="O" width="722" llx="34" lly="-14" urx="688" ury="676"/> + <char name="OE" width="889" llx="30" lly="-6" urx="885" ury="668"/> + <char name="Oacute" width="722" llx="34" lly="-14" urx="688" ury="890"/> + <char name="Ocircumflex" width="722" llx="34" lly="-14" urx="688" ury="886"/> + <char name="Odieresis" width="722" llx="34" lly="-14" urx="688" ury="835"/> + <char name="Ograve" width="722" llx="34" lly="-14" urx="688" ury="890"/> + <char name="Oslash" width="722" llx="34" lly="-80" urx="688" ury="734"/> + <char name="Otilde" width="722" llx="34" lly="-14" urx="688" ury="850"/> + <char name="P" width="556" llx="16" lly="0" urx="542" ury="662"/> + <char name="Q" width="722" llx="34" lly="-178" urx="701" ury="676"/> + <char name="R" width="667" llx="17" lly="0" urx="659" ury="662"/> + <char name="S" width="556" llx="42" lly="-14" urx="491" ury="676"/> + <char name="Scaron" width="556" llx="42" lly="-14" urx="491" ury="886"/> + <char name="T" width="611" llx="17" lly="0" urx="593" ury="662"/> + <char name="Thorn" width="556" llx="16" lly="0" urx="542" ury="662"/> + <char name="U" width="722" llx="14" lly="-14" urx="705" ury="662"/> + <char name="Uacute" width="722" llx="14" lly="-14" urx="705" ury="890"/> + <char name="Ucircumflex" width="722" llx="14" lly="-14" urx="705" ury="886"/> + <char name="Udieresis" width="722" llx="14" lly="-14" urx="705" ury="835"/> + <char name="Ugrave" width="722" llx="14" lly="-14" urx="705" ury="890"/> + <char name="V" width="722" llx="16" lly="-11" urx="697" ury="662"/> + <char name="W" width="944" llx="5" lly="-11" urx="932" ury="662"/> + <char name="X" width="722" llx="10" lly="0" urx="704" ury="662"/> + <char name="Y" width="722" llx="22" lly="0" urx="703" ury="662"/> + <char name="Yacute" width="722" llx="22" lly="0" urx="703" ury="890"/> + <char name="Ydieresis" width="722" llx="22" lly="0" urx="703" ury="835"/> + <char name="Z" width="611" llx="9" lly="0" urx="597" ury="662"/> + <char name="Zcaron" width="611" llx="9" lly="0" urx="597" ury="886"/> + <char name="a" width="444" llx="37" lly="-10" urx="442" ury="460"/> + <char name="aacute" width="444" llx="37" lly="-10" urx="442" ury="678"/> + <char name="acircumflex" width="444" llx="37" lly="-10" urx="442" ury="674"/> + <char name="acute" width="333" llx="93" lly="507" urx="317" ury="678"/> + <char name="adieresis" width="444" llx="37" lly="-10" urx="442" ury="623"/> + <char name="ae" width="667" llx="38" lly="-10" urx="632" ury="460"/> + <char name="agrave" width="444" llx="37" lly="-10" urx="442" ury="678"/> + <char name="ampersand" width="778" llx="42" lly="-13" urx="750" ury="676"/> + <char name="aring" width="444" llx="37" lly="-10" urx="442" ury="711"/> + <char name="asciicircum" width="469" llx="24" lly="297" urx="446" ury="662"/> + <char name="asciitilde" width="541" llx="40" lly="183" urx="502" ury="323"/> + <char name="asterisk" width="500" llx="69" lly="265" urx="432" ury="676"/> + <char name="at" width="921" llx="116" lly="-14" urx="809" ury="676"/> + <char name="atilde" width="444" llx="37" lly="-10" urx="442" ury="638"/> + <char name="b" width="500" llx="3" lly="-10" urx="468" ury="683"/> + <char name="backslash" width="278" llx="-9" lly="-14" urx="287" ury="676"/> + <char name="bar" width="200" llx="67" lly="-218" urx="133" ury="782"/> + <char name="braceleft" width="480" llx="100" lly="-181" urx="350" ury="680"/> + <char name="braceright" width="480" llx="130" lly="-181" urx="380" ury="680"/> + <char name="bracketleft" width="333" llx="88" lly="-156" urx="299" ury="662"/> + <char name="bracketright" width="333" llx="34" lly="-156" urx="245" ury="662"/> + <char name="breve" width="333" llx="26" lly="507" urx="307" ury="664"/> + <char name="brokenbar" width="200" llx="67" lly="-143" urx="133" ury="707"/> + <char name="bullet" width="350" llx="40" lly="196" urx="310" ury="466"/> + <char name="c" width="444" llx="25" lly="-10" urx="412" ury="460"/> + <char name="caron" width="333" llx="11" lly="507" urx="322" ury="674"/> + <char name="ccedilla" width="444" llx="25" lly="-215" urx="412" ury="460"/> + <char name="cedilla" width="333" llx="52" lly="-215" urx="261" ury="0"/> + <char name="cent" width="500" llx="53" lly="-138" urx="448" ury="579"/> + <char name="circumflex" width="333" llx="11" lly="507" urx="322" ury="674"/> + <char name="colon" width="278" llx="81" lly="-11" urx="192" ury="459"/> + <char name="comma" width="250" llx="56" lly="-141" urx="195" ury="102"/> + <char name="copyright" width="760" llx="38" lly="-14" urx="722" ury="676"/> + <char name="currency" width="500" llx="-22" lly="58" urx="522" ury="602"/> + <char name="d" width="500" llx="27" lly="-10" urx="491" ury="683"/> + <char name="dagger" width="500" llx="59" lly="-149" urx="442" ury="676"/> + <char name="daggerdbl" width="500" llx="58" lly="-153" urx="442" ury="676"/> + <char name="degree" width="400" llx="57" lly="390" urx="343" ury="676"/> + <char name="dieresis" width="333" llx="18" lly="581" urx="315" ury="681"/> + <char name="divide" width="564" llx="30" lly="-10" urx="534" ury="516"/> + <char name="dollar" width="500" llx="44" lly="-87" urx="457" ury="727"/> + <char name="dotaccent" width="333" llx="118" lly="581" urx="216" ury="681"/> + <char name="dotlessi" width="278" llx="16" lly="0" urx="253" ury="460"/> + <char name="e" width="444" llx="25" lly="-10" urx="424" ury="460"/> + <char name="eacute" width="444" llx="25" lly="-10" urx="424" ury="678"/> + <char name="ecircumflex" width="444" llx="25" lly="-10" urx="424" ury="674"/> + <char name="edieresis" width="444" llx="25" lly="-10" urx="424" ury="623"/> + <char name="egrave" width="444" llx="25" lly="-10" urx="424" ury="678"/> + <char name="eight" width="500" llx="56" lly="-14" urx="445" ury="676"/> + <char name="ellipsis" width="1000" llx="111" lly="-11" urx="888" ury="100"/> + <char name="emdash" width="1000" llx="0" lly="201" urx="1000" ury="250"/> + <char name="endash" width="500" llx="0" lly="201" urx="500" ury="250"/> + <char name="equal" width="564" llx="30" lly="120" urx="534" ury="386"/> + <char name="eth" width="500" llx="29" lly="-10" urx="471" ury="686"/> + <char name="exclam" width="333" llx="130" lly="-9" urx="238" ury="676"/> + <char name="exclamdown" width="333" llx="97" lly="-218" urx="205" ury="467"/> + <char name="f" width="333" llx="20" lly="0" urx="383" ury="683"/> + <char name="fi" width="556" llx="31" lly="0" urx="521" ury="683"/> + <char name="five" width="500" llx="32" lly="-14" urx="438" ury="688"/> + <char name="fl" width="556" llx="32" lly="0" urx="521" ury="683"/> + <char name="florin" width="500" llx="7" lly="-189" urx="490" ury="676"/> + <char name="four" width="500" llx="12" lly="0" urx="472" ury="676"/> + <char name="fraction" width="167" llx="-168" lly="-14" urx="331" ury="676"/> + <char name="g" width="500" llx="28" lly="-218" urx="470" ury="460"/> + <char name="germandbls" width="500" llx="12" lly="-9" urx="468" ury="683"/> + <char name="grave" width="333" llx="19" lly="507" urx="242" ury="678"/> + <char name="greater" width="564" llx="28" lly="-8" urx="536" ury="514"/> + <char name="guillemotleft" width="500" llx="42" lly="33" urx="456" ury="416"/> + <char name="guillemotright" width="500" llx="44" lly="33" urx="458" ury="416"/> + <char name="guilsinglleft" width="333" llx="63" lly="33" urx="285" ury="416"/> + <char name="guilsinglright" width="333" llx="48" lly="33" urx="270" ury="416"/> + <char name="h" width="500" llx="9" lly="0" urx="487" ury="683"/> + <char name="hungarumlaut" width="333" llx="-3" lly="507" urx="377" ury="678"/> + <char name="hyphen" width="333" llx="39" lly="194" urx="285" ury="257"/> + <char name="i" width="278" llx="16" lly="0" urx="253" ury="683"/> + <char name="iacute" width="278" llx="16" lly="0" urx="290" ury="678"/> + <char name="icircumflex" width="278" llx="-16" lly="0" urx="295" ury="674"/> + <char name="idieresis" width="278" llx="-9" lly="0" urx="288" ury="623"/> + <char name="igrave" width="278" llx="-8" lly="0" urx="253" ury="678"/> + <char name="j" width="278" llx="-70" lly="-218" urx="194" ury="683"/> + <char name="k" width="500" llx="7" lly="0" urx="505" ury="683"/> + <char name="l" width="278" llx="19" lly="0" urx="257" ury="683"/> + <char name="less" width="564" llx="28" lly="-8" urx="536" ury="514"/> + <char name="logicalnot" width="564" llx="30" lly="108" urx="534" ury="386"/> + <char name="lslash" width="278" llx="19" lly="0" urx="259" ury="683"/> + <char name="m" width="778" llx="16" lly="0" urx="775" ury="460"/> + <char name="macron" width="333" llx="11" lly="547" urx="322" ury="601"/> + <char name="minus" width="324" llx="30" lly="220" urx="534" ury="286"/> + <char name="mu" width="500" llx="36" lly="-218" urx="512" ury="450"/> + <char name="multiply" width="564" llx="38" lly="8" urx="527" ury="497"/> + <char name="n" width="500" llx="16" lly="0" urx="485" ury="460"/> + <char name="nine" width="500" llx="30" lly="-22" urx="459" ury="676"/> + <char name="ntilde" width="500" llx="16" lly="0" urx="485" ury="638"/> + <char name="numbersign" width="500" llx="5" lly="0" urx="496" ury="662"/> + <char name="o" width="500" llx="29" lly="-10" urx="470" ury="460"/> + <char name="oacute" width="500" llx="29" lly="-10" urx="470" ury="678"/> + <char name="ocircumflex" width="500" llx="29" lly="-10" urx="470" ury="674"/> + <char name="odieresis" width="500" llx="29" lly="-10" urx="470" ury="623"/> + <char name="oe" width="722" llx="30" lly="-10" urx="690" ury="460"/> + <char name="ogonek" width="333" llx="62" lly="-165" urx="243" ury="0"/> + <char name="ograve" width="500" llx="29" lly="-10" urx="470" ury="678"/> + <char name="one" width="500" llx="111" lly="0" urx="394" ury="676"/> + <char name="onehalf" width="750" llx="31" lly="-14" urx="746" ury="676"/> + <char name="onequarter" width="750" llx="37" lly="-14" urx="718" ury="676"/> + <char name="onesuperior" width="300" llx="57" lly="270" urx="248" ury="676"/> + <char name="ordfeminine" width="276" llx="4" lly="394" urx="270" ury="676"/> + <char name="ordmasculine" width="310" llx="6" lly="394" urx="304" ury="676"/> + <char name="oslash" width="500" llx="29" lly="-112" urx="470" ury="551"/> + <char name="otilde" width="500" llx="29" lly="-10" urx="470" ury="638"/> + <char name="p" width="500" llx="5" lly="-217" urx="470" ury="460"/> + <char name="paragraph" width="453" llx="-22" lly="-154" urx="450" ury="662"/> + <char name="parenleft" width="333" llx="48" lly="-177" urx="304" ury="676"/> + <char name="parenright" width="333" llx="29" lly="-177" urx="285" ury="676"/> + <char name="percent" width="833" llx="61" lly="-13" urx="772" ury="676"/> + <char name="period" width="250" llx="70" lly="-11" urx="181" ury="100"/> + <char name="periodcentered" width="250" llx="70" lly="199" urx="181" ury="310"/> + <char name="perthousand" width="1000" llx="7" lly="-19" urx="994" ury="706"/> + <char name="plus" width="564" llx="30" lly="0" urx="534" ury="506"/> + <char name="plusminus" width="564" llx="30" lly="0" urx="534" ury="506"/> + <char name="q" width="500" llx="24" lly="-217" urx="488" ury="460"/> + <char name="question" width="444" llx="68" lly="-8" urx="414" ury="676"/> + <char name="questiondown" width="444" llx="30" lly="-218" urx="376" ury="466"/> + <char name="quotedbl" width="408" llx="77" lly="431" urx="331" ury="676"/> + <char name="quotedblbase" width="444" llx="45" lly="-141" urx="416" ury="102"/> + <char name="quotedblleft" width="444" llx="43" lly="433" urx="414" ury="676"/> + <char name="quotedblright" width="444" llx="30" lly="433" urx="401" ury="676"/> + <char name="quoteleft" width="333" llx="115" lly="433" urx="254" ury="676"/> + <char name="quoteright" width="333" llx="79" lly="433" urx="218" ury="676"/> + <char name="quotesinglbase" width="333" llx="79" lly="-141" urx="218" ury="102"/> + <char name="quotesingle" width="180" llx="48" lly="431" urx="133" ury="676"/> + <char name="r" width="333" llx="5" lly="0" urx="335" ury="460"/> + <char name="registered" width="760" llx="38" lly="-14" urx="722" ury="676"/> + <char name="ring" width="333" llx="67" lly="512" urx="266" ury="711"/> + <char name="s" width="389" llx="51" lly="-10" urx="348" ury="460"/> + <char name="scaron" width="389" llx="39" lly="-10" urx="350" ury="674"/> + <char name="section" width="500" llx="70" lly="-148" urx="426" ury="676"/> + <char name="semicolon" width="278" llx="80" lly="-141" urx="219" ury="459"/> + <char name="seven" width="500" llx="20" lly="-8" urx="449" ury="662"/> + <char name="six" width="500" llx="34" lly="-14" urx="468" ury="684"/> + <char name="slash" width="278" llx="-9" lly="-14" urx="287" ury="676"/> + <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/> <!-- JKT: the following has been manually added --> - <char name="nbsp" width="250"/> - <char name="sterling" width="500"/> - <char name="t" width="278"/> - <char name="thorn" width="500"/> - <char name="three" width="500"/> - <char name="threequarters" width="750"/> - <char name="threesuperior" width="300"/> - <char name="tilde" width="333"/> - <char name="trademark" width="980"/> - <char name="two" width="500"/> - <char name="twosuperior" width="300"/> - <char name="u" width="500"/> - <char name="uacute" width="500"/> - <char name="ucircumflex" width="500"/> - <char name="udieresis" width="500"/> - <char name="ugrave" width="500"/> - <char name="underscore" width="500"/> - <char name="v" width="500"/> - <char name="w" width="722"/> - <char name="x" width="500"/> - <char name="y" width="500"/> - <char name="yacute" width="500"/> - <char name="ydieresis" width="500"/> - <char name="yen" width="500"/> - <char name="z" width="444"/> - <char name="zcaron" width="444"/> - <char name="zero" width="500"/> - </widths> + <char name="sterling" width="500" llx="12" lly="-8" urx="490" ury="676"/> + <char name="t" width="278" llx="13" lly="-10" urx="279" ury="579"/> + <char name="thorn" width="500" llx="5" lly="-217" urx="470" ury="683"/> + <char name="three" width="500" llx="43" lly="-14" urx="431" ury="676"/> + <char name="threequarters" width="750" llx="15" lly="-14" urx="718" ury="676"/> + <char name="threesuperior" width="300" llx="15" lly="262" urx="291" ury="676"/> + <char name="tilde" width="333" llx="1" lly="532" urx="331" ury="638"/> + <char name="trademark" width="980" llx="30" lly="256" urx="957" ury="662"/> + <char name="two" width="500" llx="30" lly="0" urx="475" ury="676"/> + <char name="twosuperior" width="300" llx="1" lly="270" urx="296" ury="676"/> + <char name="u" width="500" llx="9" lly="-10" urx="479" ury="450"/> + <char name="uacute" width="500" llx="9" lly="-10" urx="479" ury="678"/> + <char name="ucircumflex" width="500" llx="9" lly="-10" urx="479" ury="674"/> + <char name="udieresis" width="500" llx="9" lly="-10" urx="479" ury="623"/> + <char name="ugrave" width="500" llx="9" lly="-10" urx="479" ury="678"/> + <char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/> + <char name="v" width="500" llx="19" lly="-14" urx="477" ury="450"/> + <char name="w" width="722" llx="21" lly="-14" urx="694" ury="450"/> + <char name="x" width="500" llx="17" lly="0" urx="479" ury="450"/> + <char name="y" width="500" llx="14" lly="-218" urx="475" ury="450"/> + <char name="yacute" width="500" llx="14" lly="-218" urx="475" ury="678"/> + <char name="ydieresis" width="500" llx="14" lly="-218" urx="475" ury="623"/> + <char name="yen" width="500" llx="-53" lly="0" urx="512" ury="662"/> + <char name="z" width="444" llx="27" lly="0" urx="418" ury="450"/> + <char name="zcaron" width="444" llx="27" lly="0" urx="418" ury="674"/> + <char name="zero" width="500" llx="24" lly="-14" urx="476" ury="676"/> + </char-metrics> <kerning kpx1="79"> <pair kern="-35" kpx2="65"/> <pair kern="-35" kpx2="87"/> diff --git a/src/codegen/fonts/ZapfDingbats.xml b/src/codegen/fonts/ZapfDingbats.xml index f6ed76d25..bd72901dc 100644 --- a/src/codegen/fonts/ZapfDingbats.xml +++ b/src/codegen/fonts/ZapfDingbats.xml @@ -21,214 +21,216 @@ <family-name>ZapfDingbats</family-name> <class-name>ZapfDingbats</class-name> <encoding>ZapfDingbatsEncoding</encoding> + <underline-position>-100</underline-position> + <underline-thickness>50</underline-thickness> <cap-height>820</cap-height> <x-height>426</x-height> <ascender>820</ascender> <descender>-143</descender> <first-char>32</first-char> <last-char>255</last-char> - <widths> - <char name="space" width="278"/> - <char name="a1" width="974"/> - <char name="a2" width="961"/> - <char name="a202" width="974"/> - <char name="a3" width="980"/> - <char name="a4" width="719"/> - <char name="a5" width="789"/> - <char name="a119" width="790"/> - <char name="a118" width="791"/> - <char name="a117" width="690"/> - <char name="a11" width="960"/> - <char name="a12" width="939"/> - <char name="a13" width="549"/> - <char name="a14" width="855"/> - <char name="a15" width="911"/> - <char name="a16" width="933"/> - <char name="a105" width="911"/> - <char name="a17" width="945"/> - <char name="a18" width="974"/> - <char name="a19" width="755"/> - <char name="a20" width="846"/> - <char name="a21" width="762"/> - <char name="a22" width="761"/> - <char name="a23" width="571"/> - <char name="a24" width="677"/> - <char name="a25" width="763"/> - <char name="a26" width="760"/> - <char name="a27" width="759"/> - <char name="a28" width="754"/> - <char name="a6" width="494"/> - <char name="a7" width="552"/> - <char name="a8" width="537"/> - <char name="a9" width="577"/> - <char name="a10" width="692"/> - <char name="a29" width="786"/> - <char name="a30" width="788"/> - <char name="a31" width="788"/> - <char name="a32" width="790"/> - <char name="a33" width="793"/> - <char name="a34" width="794"/> - <char name="a35" width="816"/> - <char name="a36" width="823"/> - <char name="a37" width="789"/> - <char name="a38" width="841"/> - <char name="a39" width="823"/> - <char name="a40" width="833"/> - <char name="a41" width="816"/> - <char name="a42" width="831"/> - <char name="a43" width="923"/> - <char name="a44" width="744"/> - <char name="a45" width="723"/> - <char name="a46" width="749"/> - <char name="a47" width="790"/> - <char name="a48" width="792"/> - <char name="a49" width="695"/> - <char name="a50" width="776"/> - <char name="a51" width="768"/> - <char name="a52" width="792"/> - <char name="a53" width="759"/> - <char name="a54" width="707"/> - <char name="a55" width="708"/> - <char name="a56" width="682"/> - <char name="a57" width="701"/> - <char name="a58" width="826"/> - <char name="a59" width="815"/> - <char name="a60" width="789"/> - <char name="a61" width="789"/> - <char name="a62" width="707"/> - <char name="a63" width="687"/> - <char name="a64" width="696"/> - <char name="a65" width="689"/> - <char name="a66" width="786"/> - <char name="a67" width="787"/> - <char name="a68" width="713"/> - <char name="a69" width="791"/> - <char name="a70" width="785"/> - <char name="a71" width="791"/> - <char name="a72" width="873"/> - <char name="a73" width="761"/> - <char name="a74" width="762"/> - <char name="a203" width="762"/> - <char name="a75" width="759"/> - <char name="a204" width="759"/> - <char name="a76" width="892"/> - <char name="a77" width="892"/> - <char name="a78" width="788"/> - <char name="a79" width="784"/> - <char name="a81" width="438"/> - <char name="a82" width="138"/> - <char name="a83" width="277"/> - <char name="a84" width="415"/> - <char name="a97" width="392"/> - <char name="a98" width="392"/> - <char name="a99" width="668"/> - <char name="a100" width="668"/> - <char name="a101" width="732"/> - <char name="a102" width="544"/> - <char name="a103" width="544"/> - <char name="a104" width="910"/> - <char name="a106" width="667"/> - <char name="a107" width="760"/> - <char name="a108" width="760"/> - <char name="a112" width="776"/> - <char name="a111" width="595"/> - <char name="a110" width="694"/> - <char name="a109" width="626"/> - <char name="a120" width="788"/> - <char name="a121" width="788"/> - <char name="a122" width="788"/> - <char name="a123" width="788"/> - <char name="a124" width="788"/> - <char name="a125" width="788"/> - <char name="a126" width="788"/> - <char name="a127" width="788"/> - <char name="a128" width="788"/> - <char name="a129" width="788"/> - <char name="a130" width="788"/> - <char name="a131" width="788"/> - <char name="a132" width="788"/> - <char name="a133" width="788"/> - <char name="a134" width="788"/> - <char name="a135" width="788"/> - <char name="a136" width="788"/> - <char name="a137" width="788"/> - <char name="a138" width="788"/> - <char name="a139" width="788"/> - <char name="a140" width="788"/> - <char name="a141" width="788"/> - <char name="a142" width="788"/> - <char name="a143" width="788"/> - <char name="a144" width="788"/> - <char name="a145" width="788"/> - <char name="a146" width="788"/> - <char name="a147" width="788"/> - <char name="a148" width="788"/> - <char name="a149" width="788"/> - <char name="a150" width="788"/> - <char name="a151" width="788"/> - <char name="a152" width="788"/> - <char name="a153" width="788"/> - <char name="a154" width="788"/> - <char name="a155" width="788"/> - <char name="a156" width="788"/> - <char name="a157" width="788"/> - <char name="a158" width="788"/> - <char name="a159" width="788"/> - <char name="a160" width="894"/> - <char name="a161" width="838"/> - <char name="a163" width="1016"/> - <char name="a164" width="458"/> - <char name="a196" width="748"/> - <char name="a165" width="924"/> - <char name="a192" width="748"/> - <char name="a166" width="918"/> - <char name="a167" width="927"/> - <char name="a168" width="928"/> - <char name="a169" width="928"/> - <char name="a170" width="834"/> - <char name="a171" width="873"/> - <char name="a172" width="828"/> - <char name="a173" width="924"/> - <char name="a162" width="924"/> - <char name="a174" width="917"/> - <char name="a175" width="930"/> - <char name="a176" width="931"/> - <char name="a177" width="463"/> - <char name="a178" width="883"/> - <char name="a179" width="836"/> - <char name="a193" width="836"/> - <char name="a180" width="867"/> - <char name="a199" width="867"/> - <char name="a181" width="696"/> - <char name="a200" width="696"/> - <char name="a182" width="874"/> - <char name="a201" width="874"/> - <char name="a183" width="760"/> - <char name="a184" width="946"/> - <char name="a197" width="771"/> - <char name="a185" width="865"/> - <char name="a194" width="771"/> - <char name="a198" width="888"/> - <char name="a186" width="967"/> - <char name="a195" width="888"/> - <char name="a187" width="831"/> - <char name="a188" width="873"/> - <char name="a189" width="927"/> - <char name="a190" width="970"/> - <char name="a191" width="918"/> - <char name="a86" width="410"/> - <char name="a85" width="509"/> - <char name="a95" width="334"/> - <char name="a205" width="509"/> - <char name="a89" width="390"/> - <char name="a87" width="234"/> - <char name="a91" width="276"/> - <char name="a90" width="390"/> - <char name="a206" width="410"/> - <char name="a94" width="317"/> - <char name="a93" width="317"/> - <char name="a92" width="276"/> - <char name="a96" width="334"/> - <char name="a88" width="234"/> - </widths> -</font-metrics>
\ No newline at end of file + <char-metrics> + <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/> + <char name="a1" width="974" llx="35" lly="72" urx="939" ury="621"/> + <char name="a2" width="961" llx="35" lly="81" urx="927" ury="611"/> + <char name="a202" width="974" llx="35" lly="72" urx="939" ury="621"/> + <char name="a3" width="980" llx="35" lly="0" urx="945" ury="692"/> + <char name="a4" width="719" llx="34" lly="139" urx="685" ury="566"/> + <char name="a5" width="789" llx="35" lly="-14" urx="755" ury="705"/> + <char name="a119" width="790" llx="35" lly="-14" urx="755" ury="705"/> + <char name="a118" width="791" llx="35" lly="-13" urx="761" ury="705"/> + <char name="a117" width="690" llx="34" lly="138" urx="655" ury="553"/> + <char name="a11" width="960" llx="35" lly="123" urx="925" ury="568"/> + <char name="a12" width="939" llx="35" lly="134" urx="904" ury="559"/> + <char name="a13" width="549" llx="29" lly="-11" urx="516" ury="705"/> + <char name="a14" width="855" llx="34" lly="59" urx="820" ury="632"/> + <char name="a15" width="911" llx="35" lly="50" urx="876" ury="642"/> + <char name="a16" width="933" llx="35" lly="139" urx="899" ury="550"/> + <char name="a105" width="911" llx="35" lly="50" urx="876" ury="642"/> + <char name="a17" width="945" llx="35" lly="139" urx="909" ury="553"/> + <char name="a18" width="974" llx="35" lly="104" urx="938" ury="587"/> + <char name="a19" width="755" llx="34" lly="-13" urx="721" ury="705"/> + <char name="a20" width="846" llx="36" lly="-14" urx="811" ury="705"/> + <char name="a21" width="762" llx="35" lly="0" urx="727" ury="692"/> + <char name="a22" width="761" llx="35" lly="0" urx="727" ury="692"/> + <char name="a23" width="571" llx="-1" lly="-68" urx="571" ury="661"/> + <char name="a24" width="677" llx="36" lly="-13" urx="642" ury="705"/> + <char name="a25" width="763" llx="35" lly="0" urx="728" ury="692"/> + <char name="a26" width="760" llx="35" lly="0" urx="726" ury="692"/> + <char name="a27" width="759" llx="35" lly="0" urx="725" ury="692"/> + <char name="a28" width="754" llx="35" lly="0" urx="720" ury="692"/> + <char name="a6" width="494" llx="35" lly="0" urx="460" ury="692"/> + <char name="a7" width="552" llx="35" lly="0" urx="517" ury="692"/> + <char name="a8" width="537" llx="35" lly="0" urx="503" ury="692"/> + <char name="a9" width="577" llx="35" lly="96" urx="542" ury="596"/> + <char name="a10" width="692" llx="35" lly="-14" urx="657" ury="705"/> + <char name="a29" width="786" llx="35" lly="-14" urx="751" ury="705"/> + <char name="a30" width="788" llx="35" lly="-14" urx="752" ury="705"/> + <char name="a31" width="788" llx="35" lly="-14" urx="753" ury="705"/> + <char name="a32" width="790" llx="35" lly="-14" urx="756" ury="705"/> + <char name="a33" width="793" llx="35" lly="-13" urx="759" ury="705"/> + <char name="a34" width="794" llx="35" lly="-13" urx="759" ury="705"/> + <char name="a35" width="816" llx="35" lly="-14" urx="782" ury="705"/> + <char name="a36" width="823" llx="35" lly="-14" urx="787" ury="705"/> + <char name="a37" width="789" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a38" width="841" llx="35" lly="-14" urx="807" ury="705"/> + <char name="a39" width="823" llx="35" lly="-14" urx="789" ury="705"/> + <char name="a40" width="833" llx="35" lly="-14" urx="798" ury="705"/> + <char name="a41" width="816" llx="35" lly="-13" urx="782" ury="705"/> + <char name="a42" width="831" llx="35" lly="-14" urx="796" ury="705"/> + <char name="a43" width="923" llx="35" lly="-14" urx="888" ury="705"/> + <char name="a44" width="744" llx="35" lly="0" urx="710" ury="692"/> + <char name="a45" width="723" llx="35" lly="0" urx="688" ury="692"/> + <char name="a46" width="749" llx="35" lly="0" urx="714" ury="692"/> + <char name="a47" width="790" llx="34" lly="-14" urx="756" ury="705"/> + <char name="a48" width="792" llx="35" lly="-14" urx="758" ury="705"/> + <char name="a49" width="695" llx="35" lly="-14" urx="661" ury="706"/> + <char name="a50" width="776" llx="35" lly="-6" urx="741" ury="699"/> + <char name="a51" width="768" llx="35" lly="-7" urx="734" ury="699"/> + <char name="a52" width="792" llx="35" lly="-14" urx="757" ury="705"/> + <char name="a53" width="759" llx="35" lly="0" urx="725" ury="692"/> + <char name="a54" width="707" llx="35" lly="-13" urx="672" ury="704"/> + <char name="a55" width="708" llx="35" lly="-14" urx="672" ury="705"/> + <char name="a56" width="682" llx="35" lly="-14" urx="647" ury="705"/> + <char name="a57" width="701" llx="35" lly="-14" urx="666" ury="705"/> + <char name="a58" width="826" llx="35" lly="-14" urx="791" ury="705"/> + <char name="a59" width="815" llx="35" lly="-14" urx="780" ury="705"/> + <char name="a60" width="789" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a61" width="789" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a62" width="707" llx="34" lly="-14" urx="673" ury="705"/> + <char name="a63" width="687" llx="36" lly="0" urx="651" ury="692"/> + <char name="a64" width="696" llx="35" lly="0" urx="661" ury="691"/> + <char name="a65" width="689" llx="35" lly="0" urx="655" ury="692"/> + <char name="a66" width="786" llx="34" lly="-14" urx="751" ury="705"/> + <char name="a67" width="787" llx="35" lly="-14" urx="752" ury="705"/> + <char name="a68" width="713" llx="35" lly="-14" urx="678" ury="705"/> + <char name="a69" width="791" llx="35" lly="-14" urx="756" ury="705"/> + <char name="a70" width="785" llx="36" lly="-14" urx="751" ury="705"/> + <char name="a71" width="791" llx="35" lly="-14" urx="757" ury="705"/> + <char name="a72" width="873" llx="35" lly="-14" urx="838" ury="705"/> + <char name="a73" width="761" llx="35" lly="0" urx="726" ury="692"/> + <char name="a74" width="762" llx="35" lly="0" urx="727" ury="692"/> + <char name="a203" width="762" llx="35" lly="0" urx="727" ury="692"/> + <char name="a75" width="759" llx="35" lly="0" urx="725" ury="692"/> + <char name="a204" width="759" llx="35" lly="0" urx="725" ury="692"/> + <char name="a76" width="892" llx="35" lly="0" urx="858" ury="705"/> + <char name="a77" width="892" llx="35" lly="-14" urx="858" ury="692"/> + <char name="a78" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a79" width="784" llx="35" lly="-14" urx="749" ury="705"/> + <char name="a81" width="438" llx="35" lly="-14" urx="403" ury="705"/> + <char name="a82" width="138" llx="35" lly="0" urx="104" ury="692"/> + <char name="a83" width="277" llx="35" lly="0" urx="242" ury="692"/> + <char name="a84" width="415" llx="35" lly="0" urx="380" ury="692"/> + <char name="a97" width="392" llx="35" lly="263" urx="357" ury="705"/> + <char name="a98" width="392" llx="34" lly="263" urx="357" ury="705"/> + <char name="a99" width="668" llx="35" lly="263" urx="633" ury="705"/> + <char name="a100" width="668" llx="36" lly="263" urx="634" ury="705"/> + <char name="a101" width="732" llx="35" lly="-143" urx="697" ury="806"/> + <char name="a102" width="544" llx="56" lly="-14" urx="488" ury="706"/> + <char name="a103" width="544" llx="34" lly="-14" urx="508" ury="705"/> + <char name="a104" width="910" llx="35" lly="40" urx="875" ury="651"/> + <char name="a106" width="667" llx="35" lly="-14" urx="633" ury="705"/> + <char name="a107" width="760" llx="35" lly="-14" urx="726" ury="705"/> + <char name="a108" width="760" llx="0" lly="121" urx="758" ury="569"/> + <char name="a112" width="776" llx="35" lly="0" urx="741" ury="705"/> + <char name="a111" width="595" llx="34" lly="-14" urx="560" ury="705"/> + <char name="a110" width="694" llx="35" lly="-14" urx="659" ury="705"/> + <char name="a109" width="626" llx="34" lly="0" urx="591" ury="705"/> + <char name="a120" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a121" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a122" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a123" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a124" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a125" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a126" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a127" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a128" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a129" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a130" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a131" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a132" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a133" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a134" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a135" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a136" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a137" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a138" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a139" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a140" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a141" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a142" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a143" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a144" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a145" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a146" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a147" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a148" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a149" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a150" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a151" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a152" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a153" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a154" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a155" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a156" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a157" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a158" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a159" width="788" llx="35" lly="-14" urx="754" ury="705"/> + <char name="a160" width="894" llx="35" lly="58" urx="860" ury="634"/> + <char name="a161" width="838" llx="35" lly="152" urx="803" ury="540"/> + <char name="a163" width="1016" llx="34" lly="152" urx="981" ury="540"/> + <char name="a164" width="458" llx="35" lly="-127" urx="422" ury="820"/> + <char name="a196" width="748" llx="35" lly="94" urx="698" ury="597"/> + <char name="a165" width="924" llx="35" lly="140" urx="890" ury="552"/> + <char name="a192" width="748" llx="35" lly="94" urx="698" ury="597"/> + <char name="a166" width="918" llx="35" lly="166" urx="884" ury="526"/> + <char name="a167" width="927" llx="35" lly="32" urx="892" ury="660"/> + <char name="a168" width="928" llx="35" lly="129" urx="891" ury="562"/> + <char name="a169" width="928" llx="35" lly="128" urx="893" ury="563"/> + <char name="a170" width="834" llx="35" lly="155" urx="799" ury="537"/> + <char name="a171" width="873" llx="35" lly="93" urx="838" ury="599"/> + <char name="a172" width="828" llx="35" lly="104" urx="791" ury="588"/> + <char name="a173" width="924" llx="35" lly="98" urx="889" ury="594"/> + <char name="a162" width="924" llx="35" lly="98" urx="889" ury="594"/> + <char name="a174" width="917" llx="35" lly="0" urx="882" ury="692"/> + <char name="a175" width="930" llx="35" lly="84" urx="896" ury="608"/> + <char name="a176" width="931" llx="35" lly="84" urx="896" ury="608"/> + <char name="a177" width="463" llx="35" lly="-99" urx="429" ury="791"/> + <char name="a178" width="883" llx="35" lly="71" urx="848" ury="623"/> + <char name="a179" width="836" llx="35" lly="44" urx="802" ury="648"/> + <char name="a193" width="836" llx="35" lly="44" urx="802" ury="648"/> + <char name="a180" width="867" llx="35" lly="101" urx="832" ury="591"/> + <char name="a199" width="867" llx="35" lly="101" urx="832" ury="591"/> + <char name="a181" width="696" llx="35" lly="44" urx="661" ury="648"/> + <char name="a200" width="696" llx="35" lly="44" urx="661" ury="648"/> + <char name="a182" width="874" llx="35" lly="77" urx="840" ury="619"/> + <char name="a201" width="874" llx="35" lly="73" urx="840" ury="615"/> + <char name="a183" width="760" llx="35" lly="0" urx="725" ury="692"/> + <char name="a184" width="946" llx="35" lly="160" urx="911" ury="533"/> + <char name="a197" width="771" llx="34" lly="37" urx="736" ury="655"/> + <char name="a185" width="865" llx="35" lly="207" urx="830" ury="481"/> + <char name="a194" width="771" llx="34" lly="37" urx="736" ury="655"/> + <char name="a198" width="888" llx="34" lly="-19" urx="853" ury="712"/> + <char name="a186" width="967" llx="35" lly="124" urx="932" ury="568"/> + <char name="a195" width="888" llx="34" lly="-19" urx="853" ury="712"/> + <char name="a187" width="831" llx="35" lly="113" urx="796" ury="579"/> + <char name="a188" width="873" llx="36" lly="118" urx="838" ury="578"/> + <char name="a189" width="927" llx="35" lly="150" urx="891" ury="542"/> + <char name="a190" width="970" llx="35" lly="76" urx="931" ury="616"/> + <char name="a191" width="918" llx="34" lly="99" urx="884" ury="593"/> + <char name="a86" width="410" llx="35" lly="0" urx="375" ury="692"/> + <char name="a85" width="509" llx="35" lly="0" urx="475" ury="692"/> + <char name="a95" width="334" llx="35" lly="0" urx="299" ury="692"/> + <char name="a205" width="509" llx="35" lly="0" urx="475" ury="692"/> + <char name="a89" width="390" llx="35" lly="-14" urx="356" ury="705"/> + <char name="a87" width="234" llx="35" lly="-14" urx="199" ury="705"/> + <char name="a91" width="276" llx="35" lly="0" urx="242" ury="692"/> + <char name="a90" width="390" llx="35" lly="-14" urx="355" ury="705"/> + <char name="a206" width="410" llx="35" lly="0" urx="375" ury="692"/> + <char name="a94" width="317" llx="35" lly="0" urx="283" ury="692"/> + <char name="a93" width="317" llx="35" lly="0" urx="283" ury="692"/> + <char name="a92" width="276" llx="35" lly="0" urx="242" ury="692"/> + <char name="a96" width="334" llx="35" lly="0" urx="299" ury="692"/> + <char name="a88" width="234" llx="35" lly="-14" urx="199" ury="705"/> + </char-metrics> +</font-metrics> diff --git a/src/codegen/fonts/font-file.xsl b/src/codegen/fonts/font-file.xsl index 85b968808..8723ed960 100644 --- a/src/codegen/fonts/font-file.xsl +++ b/src/codegen/fonts/font-file.xsl @@ -35,6 +35,7 @@ <xsl:template match="font-metrics"> package org.apache.fop.fonts.base14; +import java.awt.Rectangle; <xsl:if test="count(kerning) > 0"> import java.util.Map; </xsl:if> @@ -42,12 +43,14 @@ import java.util.Set; import org.apache.fop.fonts.FontType; import org.apache.fop.fonts.Base14Font; import org.apache.fop.fonts.CodePointMapping; -import org.apache.fop.fonts.Typeface;; +import org.apache.fop.fonts.Typeface; public class <xsl:value-of select="class-name"/> extends Base14Font { private final static String fontName = "<xsl:value-of select="font-name"/>"; private final static String fullName = "<xsl:value-of select="full-name"/>"; private final static Set familyNames; + private final static int underlinePosition = <xsl:value-of select="underline-position"/>; + private final static int underlineThickness = <xsl:value-of select="underline-thickness"/>; private final static String encoding = "<xsl:value-of select="$encoding"/>"; private final static int capHeight = <xsl:value-of select="cap-height"/>; private final static int xHeight = <xsl:value-of select="x-height"/>; @@ -56,6 +59,7 @@ public class <xsl:value-of select="class-name"/> extends Base14Font { private final static int firstChar = <xsl:value-of select="first-char"/>; private final static int lastChar = <xsl:value-of select="last-char"/>; private final static int[] width; + private final static Rectangle[] boundingBoxes; private final CodePointMapping mapping = CodePointMapping.getMapping("<xsl:value-of select="$encoding"/>"); <xsl:if test="count(kerning) > 0"> @@ -66,7 +70,8 @@ public class <xsl:value-of select="class-name"/> extends Base14Font { static { width = new int[256]; - <xsl:apply-templates select="widths"/> + boundingBoxes = new Rectangle[256]; + <xsl:apply-templates select="char-metrics"/> <xsl:if test="count(kerning) > 0"> kerning = new java.util.HashMap(); Integer first, second; @@ -125,6 +130,14 @@ public class <xsl:value-of select="class-name"/> extends Base14Font { return size * xHeight; } + public int getUnderlinePosition(int size) { + return size * underlinePosition; + } + + public int getUnderlineThickness(int size) { + return size * underlineThickness; + } + public int getFirstChar() { return firstChar; } @@ -137,6 +150,11 @@ public class <xsl:value-of select="class-name"/> extends Base14Font { return size * width[i]; } + public Rectangle getBoundingBox(int glyphIndex, int size) { + Rectangle bbox = boundingBoxes[glyphIndex]; + return new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size); + } + public int[] getWidths() { int[] arr = new int[getLastChar() - getFirstChar() + 1]; System.arraycopy(width, getFirstChar(), arr, 0, getLastChar() - getFirstChar() + 1); @@ -182,7 +200,9 @@ public class <xsl:value-of select="class-name"/> extends Base14Font { } </xsl:template> - <xsl:template match="widths/char"><xsl:variable name="char-name" select="@name"/><xsl:variable name="char-num" select="$glyphs[@name = $char-name]/@codepoint"/><xsl:if test="$char-num!=''"> width[0x<xsl:value-of select="$char-num"/>] = <xsl:value-of select="@width"/>;</xsl:if></xsl:template> + <xsl:template match="char-metrics/char"> + <xsl:variable name="char-name" select="@name"/><xsl:variable name="char-num" select="$glyphs[@name = $char-name]/@codepoint"/><xsl:if test="$char-num!=''"> width[0x<xsl:value-of select="$char-num"/>] = <xsl:value-of select="@width"/>; + boundingBoxes[0x<xsl:value-of select="$char-num"/>] = new Rectangle(<xsl:value-of select="@llx"/>,<xsl:value-of select="@lly"/>,<xsl:value-of select="@urx - @llx"/>,<xsl:value-of select="@ury - @lly"/>);</xsl:if></xsl:template> <xsl:template match="kerning"> first = new Integer(<xsl:value-of select="@kpx1"/>); diff --git a/src/java/org/apache/fop/Version.java b/src/java/org/apache/fop/Version.java index 86861a60b..a8903c74e 100644 --- a/src/java/org/apache/fop/Version.java +++ b/src/java/org/apache/fop/Version.java @@ -40,8 +40,9 @@ public final class Version { } if (version == null) { //Fallback if FOP is used in a development environment - String headURL - = "$HeadURL$"; + // CSOFF: LineLength + String headURL = "$HeadURL$"; + // CSON: LineLength version = headURL; final String pathPrefix = "/xmlgraphics/fop/"; int pos = version.indexOf(pathPrefix); diff --git a/src/java/org/apache/fop/afp/AFPEventProducer.java b/src/java/org/apache/fop/afp/AFPEventProducer.java index 01d5c4ad7..1b43400c5 100644 --- a/src/java/org/apache/fop/afp/AFPEventProducer.java +++ b/src/java/org/apache/fop/afp/AFPEventProducer.java @@ -122,4 +122,12 @@ public interface AFPEventProducer extends EventProducer { * @event.severity WARN */ void charactersetMissingMetrics(Object source, char character, String charSet); + + /** + * Double-byte fonts are not currently supported in SVG. + * @param source the event source + * @param fontFamily name of DB font + * @event.severity WARN + */ + void invalidDBFontInSVG(Object source, String fontFamily); } diff --git a/src/java/org/apache/fop/afp/fonts/AFPFont.java b/src/java/org/apache/fop/afp/fonts/AFPFont.java index 06f484f37..99e15a46b 100644 --- a/src/java/org/apache/fop/afp/fonts/AFPFont.java +++ b/src/java/org/apache/fop/afp/fonts/AFPFont.java @@ -19,6 +19,7 @@ package org.apache.fop.afp.fonts; +import java.awt.Rectangle; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -34,6 +35,8 @@ import org.apache.fop.fonts.Typeface; */ public abstract class AFPFont extends Typeface { + private static final double STRIKEOUT_POSITION_FACTOR = 0.45; + /** The font name */ protected final String name; @@ -117,7 +120,34 @@ public abstract class AFPFont extends Typeface { */ protected static final char toUnicodeCodepoint(int character) { //AFP fonts use Unicode directly as their mapped code points, so we can simply cast to char - return (char)character; + return (char) character; + } + + /** {@inheritDoc} */ + public int getUnderlineThickness(int size) { + // This is the FOCA recommendation in the absence of the Underline Thickness parameter + return getBoundingBox('-', size).height; + } + + /** {@inheritDoc} */ + public int getStrikeoutPosition(int size) { + //TODO This conflicts with the FOCA recommendation of 0 in the absence of the Throughscore Position + // parameter + return (int) (STRIKEOUT_POSITION_FACTOR * getCapHeight(size)); + } + + /** {@inheritDoc} */ + public int getStrikeoutThickness(int size) { + // This is the FOCA recommendation in the absence of the Throughscore Thickness parameter + return getBoundingBox('-', size).height; + } + + /** {@inheritDoc} */ + public abstract Rectangle getBoundingBox(int glyphIndex, int size); + + /** {@inheritDoc} */ + public int[] getWidths() { + throw new UnsupportedOperationException(); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java index 7b57a2b8c..edbdf5e95 100644 --- a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java +++ b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java @@ -71,22 +71,6 @@ public abstract class AbstractOutlineFont extends AFPFont { } /** - * Get the first character in this font. - * @return the first character in this font - */ - public int getFirstChar() { - return charSet.getFirstChar(); - } - - /** - * Get the last character in this font. - * @return the last character in this font - */ - public int getLastChar() { - return charSet.getLastChar(); - } - - /** * The ascender is the part of a lowercase letter that extends above the * "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also * used to denote the part of the letter extending above the x-height. @@ -98,6 +82,17 @@ public abstract class AbstractOutlineFont extends AFPFont { return charSet.getAscender() * size; } + /** {@inheritDoc} */ + public int getUnderlinePosition(int size) { + return charSet.getUnderscorePosition() * size; + } + + @Override + public int getUnderlineThickness(int size) { + int underscoreWidth = charSet.getUnderscoreWidth(); + return underscoreWidth == 0 ? super.getUnderlineThickness(size) : underscoreWidth * size; + } + /** * Obtains the height of capital letters for the specified point size. * @@ -130,40 +125,7 @@ public abstract class AbstractOutlineFont extends AFPFont { return charSet.getXHeight() * size; } - /** - * Obtain the width of the character for the specified point size. - * @param character the character - * @param size the font size (in mpt) - * @return the width of the character for the specified point size - */ - public int getWidth(int character, int size) { - return charSet.getWidth(toUnicodeCodepoint(character)) * size; - } - /** - * Get the getWidth (in 1/1000ths of a point size) of all characters in this - * character set. - * - * @param size the font size (in mpt) - * @return the widths of all characters - */ - public int[] getWidths(int size) { - int[] widths = charSet.getWidths(); - for (int i = 0; i < widths.length; i++) { - widths[i] = widths[i] * size; - } - return widths; - } - - /** - * Get the getWidth (in 1/1000ths of a point size) of all characters in this - * character set. - * - * @return the widths of all characters - */ - public int[] getWidths() { - return getWidths(1000); - } /** {@inheritDoc} */ public boolean hasChar(char c) { diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/afp/fonts/CharacterSet.java index e0c3b9c9a..3df8ba4c4 100644 --- a/src/java/org/apache/fop/afp/fonts/CharacterSet.java +++ b/src/java/org/apache/fop/afp/fonts/CharacterSet.java @@ -19,10 +19,9 @@ package org.apache.fop.afp.fonts; +import java.awt.Rectangle; import java.io.UnsupportedEncodingException; import java.nio.charset.CharacterCodingException; -import java.util.HashMap; -import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -63,6 +62,8 @@ public class CharacterSet { private static final int MAX_NAME_LEN = 8; + /** The current orientation (currently only 0 is supported by FOP) */ + public static final int SUPPORTED_ORIENTATION = 0; /** The code page to which the character set relates */ protected final String codePage; @@ -79,11 +80,8 @@ public class CharacterSet { /** The path to the installed fonts */ private final AFPResourceAccessor accessor; - /** The current orientation (currently only 0 is supported by FOP) */ - private final String currentOrientation = "0"; - /** The collection of objects for each orientation */ - private final Map<String, CharacterSetOrientation> characterSetOrientations; + private CharacterSetOrientation characterSetOrientation; /** The nominal vertical size (in millipoints) for bitmap fonts. 0 for outline fonts. */ private int nominalVerticalSize; @@ -116,8 +114,6 @@ public class CharacterSet { this.encoding = encoding; this.encoder = charsetType.getEncoder(encoding); this.accessor = accessor; - - this.characterSetOrientations = new HashMap<String, CharacterSetOrientation>(4); } // right pad short names with space @@ -131,7 +127,9 @@ public class CharacterSet { * @param cso the metrics for the orientation */ public void addCharacterSetOrientation(CharacterSetOrientation cso) { - characterSetOrientations.put(String.valueOf(cso.getOrientation()), cso); + if (cso.getOrientation() == SUPPORTED_ORIENTATION) { + characterSetOrientation = cso; + } } /** @@ -165,11 +163,24 @@ public class CharacterSet { * @return the ascender value in millipoints */ public int getAscender() { - return getCharacterSetOrientation().getAscender(); } /** + * TODO + */ + public int getUnderscoreWidth() { + return getCharacterSetOrientation().getUnderscoreWidth(); + } + + /** + * TODO + */ + public int getUnderscorePosition() { + return getCharacterSetOrientation().getUnderscorePosition(); + } + + /** * Cap height is the average height of the uppercase characters in * a font. This value is specified by the designer of a font and is * usually the height of the uppercase M. @@ -177,7 +188,6 @@ public class CharacterSet { * @return the cap height value in millipoints */ public int getCapHeight() { - return getCharacterSetOrientation().getCapHeight(); } @@ -194,24 +204,6 @@ public class CharacterSet { } /** - * Returns the first character in the character set - * - * @return the first character in the character set (Unicode codepoint) - */ - public char getFirstChar() { - return getCharacterSetOrientation().getFirstChar(); - } - - /** - * Returns the last character in the character set - * - * @return the last character in the character set (Unicode codepoint) - */ - public char getLastChar() { - return getCharacterSetOrientation().getLastChar(); - } - - /** * Returns the resource accessor to load the font resources with. * @return the resource accessor to load the font resources with */ @@ -220,16 +212,6 @@ public class CharacterSet { } /** - * Get the width (in 1/1000ths of a point size) of all characters - * - * @return the widths of all characters - */ - public int[] getWidths() { - - return getCharacterSetOrientation().getWidths(); - } - - /** * XHeight refers to the height of the lower case letters above the baseline. * * @return the typical height of characters @@ -246,11 +228,13 @@ public class CharacterSet { * @param character the Unicode character from which the width will be calculated * @return the width of the character */ - public int getWidth(char character) { - return getCharacterSetOrientation().getWidth(character); + public int getWidth(char character, int size) { + return getCharacterSetOrientation().getWidth(character, size); } - + public Rectangle getCharacterBox(char character, int size) { + return getCharacterSetOrientation().getCharacterBox(character, size); + } /** * Returns the AFP character set identifier @@ -309,9 +293,7 @@ public class CharacterSet { * @return characterSetOrentation The current orientation metrics. */ private CharacterSetOrientation getCharacterSetOrientation() { - CharacterSetOrientation c - = characterSetOrientations.get(currentOrientation); - return c; + return characterSetOrientation; } /** diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java index 2565942b5..a3b2ab8ec 100644 --- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java +++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java @@ -19,6 +19,7 @@ package org.apache.fop.afp.fonts; +import java.awt.Rectangle; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; @@ -292,16 +293,14 @@ public abstract class CharacterSetBuilder { metricNormalizationFactor = 1000.0d * 72000.0d / fontDescriptor.getNominalFontSizeInMillipoints() / dpi; } - + ValueNormalizer normalizer = new ValueNormalizer(metricNormalizationFactor); //process D3AC89 Font Position - processFontPosition(structuredFieldReader, characterSetOrientations, - metricNormalizationFactor); - + processFontPosition(structuredFieldReader, characterSetOrientations, normalizer); //process D38C89 Font Index (per orientation) for (int i = 0; i < characterSetOrientations.length; i++) { - processFontIndex(structuredFieldReader, - characterSetOrientations[i], codePage, metricNormalizationFactor); - characterSet.addCharacterSetOrientation(characterSetOrientations[i]); + CharacterSetOrientation characterSetOrientation = characterSetOrientations[i]; + processFontIndex(structuredFieldReader, characterSetOrientation, codePage, normalizer); + characterSet.addCharacterSetOrientation(characterSetOrientation); } } else { throw new IOException("Missing D3AE89 Font Control structured field."); @@ -314,6 +313,19 @@ public abstract class CharacterSetBuilder { return characterSet; } + private static class ValueNormalizer { + + private final double factor; + + public ValueNormalizer(double factor) { + this.factor = factor; + } + + public int normalize(int value) { + return (int) Math.round(value * factor); + } + } + /** * Load the code page information from the appropriate file. The file name * to load is determined by the code page name and the file extension 'CDP'. @@ -475,7 +487,7 @@ public abstract class CharacterSetBuilder { * @throws IOException if an I/O exception of some sort has occurred. */ private void processFontPosition(StructuredFieldReader structuredFieldReader, - CharacterSetOrientation[] characterSetOrientations, double metricNormalizationFactor) + CharacterSetOrientation[] characterSetOrientations, ValueNormalizer normalizer) throws IOException { byte[] data = structuredFieldReader.getNext(FONT_POSITION_SF); @@ -493,48 +505,34 @@ public abstract class CharacterSetBuilder { if (position == 9) { CharacterSetOrientation characterSetOrientation = characterSetOrientations[characterSetOrientationIndex]; - int xHeight = getSBIN(fpData, 2); int capHeight = getSBIN(fpData, 4); int ascHeight = getSBIN(fpData, 6); int dscHeight = getSBIN(fpData, 8); - dscHeight = dscHeight * -1; - - characterSetOrientation.setXHeight( - (int)Math.round(xHeight * metricNormalizationFactor)); - characterSetOrientation.setCapHeight( - (int)Math.round(capHeight * metricNormalizationFactor)); - characterSetOrientation.setAscender( - (int)Math.round(ascHeight * metricNormalizationFactor)); - characterSetOrientation.setDescender( - (int)Math.round(dscHeight * metricNormalizationFactor)); + int underscoreWidth = getUBIN(fpData, 17); + int underscorePosition = getSBIN(fpData, 20); + characterSetOrientation.setXHeight(normalizer.normalize(xHeight)); + characterSetOrientation.setCapHeight(normalizer.normalize(capHeight)); + characterSetOrientation.setAscender(normalizer.normalize(ascHeight)); + characterSetOrientation.setDescender(normalizer.normalize(dscHeight)); + characterSetOrientation.setUnderscoreWidth(normalizer.normalize(underscoreWidth)); + characterSetOrientation.setUnderscorePosition(normalizer.normalize(underscorePosition)); } } else if (position == 22) { position = 0; characterSetOrientationIndex++; fpData[position] = data[index]; } - position++; } } - /** - * Process the font index details for the character set orientation. - * - * @param structuredFieldReader the structured field reader - * @param cso the CharacterSetOrientation object to populate - * @param codepage the map of code pages - * @param metricNormalizationFactor factor to apply to the metrics to get normalized - * font metric values - * @throws IOException if an I/O exception of some sort has occurred. - */ - private void processFontIndex(StructuredFieldReader structuredFieldReader, - CharacterSetOrientation cso, Map<String, String> codepage, - double metricNormalizationFactor) - throws IOException { + + private void processFontIndex(StructuredFieldReader structuredFieldReader, CharacterSetOrientation cso, + Map<String, String> codepage, ValueNormalizer normalizer) + throws IOException { byte[] data = structuredFieldReader.getNext(FONT_INDEX_SF); @@ -543,8 +541,6 @@ public abstract class CharacterSetBuilder { byte[] gcgid = new byte[8]; byte[] fiData = new byte[20]; - char lowest = 255; - char highest = 0; String firstABCMismatch = null; // Read data, ignoring bytes 0 - 2 @@ -569,13 +565,15 @@ public abstract class CharacterSetBuilder { char cidx = idx.charAt(0); int width = getUBIN(fiData, 0); + int ascendHt = getSBIN(fiData, 2); + int descendDp = getSBIN(fiData, 4); int a = getSBIN(fiData, 10); int b = getUBIN(fiData, 12); int c = getSBIN(fiData, 14); int abc = a + b + c; int diff = Math.abs(abc - width); if (diff != 0 && width != 0) { - double diffPercent = 100 * diff / (double)width; + double diffPercent = 100 * diff / (double) width; if (diffPercent > 2) { if (LOG.isTraceEnabled()) { LOG.trace(gcgiString + ": " @@ -587,27 +585,16 @@ public abstract class CharacterSetBuilder { } } } - - if (cidx < lowest) { - lowest = cidx; - } - - if (cidx > highest) { - highest = cidx; - } - - int normalizedWidth = (int)Math.round(width * metricNormalizationFactor); - - cso.setWidth(cidx, normalizedWidth); - + int normalizedWidth = normalizer.normalize(width); + int x0 = normalizer.normalize(a); + int y0 = normalizer.normalize(-descendDp); + int dx = normalizer.normalize(b); + int dy = normalizer.normalize(ascendHt + descendDp); + cso.setCharacterMetrics(cidx, normalizedWidth, new Rectangle(x0, y0, dx, dy)); } - } } - cso.setFirstChar(lowest); - cso.setLastChar(highest); - if (LOG.isDebugEnabled() && firstABCMismatch != null) { //Debug level because it usually is no problem. LOG.debug("Font has metrics inconsitencies where A+B+C doesn't equal the" diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java b/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java index a730525d2..5fe524536 100644 --- a/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java +++ b/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java @@ -19,7 +19,7 @@ package org.apache.fop.afp.fonts; -import java.util.Arrays; +import java.awt.Rectangle; /** * The IBM Font Object Content Architecture (FOCA) supports presentation @@ -60,23 +60,13 @@ public class CharacterSetOrientation { /** * The character widths in the character set (indexed using Unicode codepoints) */ - private int[] charsWidths; + private IntegerKeyStore<CharacterMetrics> characterMetrics; /** * The height of lowercase letters */ private int xHeight; - /** - * The first character (Unicode codepoint) - */ - private char firstChar; - - /** - * The last character (Unicode codepoint) - */ - private char lastChar; - /** The character set orientation */ private final int orientation; /** space increment */ @@ -86,6 +76,10 @@ public class CharacterSetOrientation { /** Nominal Character Increment */ private final int nomCharIncrement; + private int underscoreWidth; + + private int underscorePosition; + /** * Constructor for the CharacterSetOrientation, the orientation is * expressed as the degrees rotation (i.e 0, 90, 180, 270) @@ -97,8 +91,7 @@ public class CharacterSetOrientation { this.spaceIncrement = spaceIncrement; this.emSpaceIncrement = emSpaceIncrement; this.nomCharIncrement = nomCharIncrement; - charsWidths = new int[256]; - Arrays.fill(charsWidths, -1); + this.characterMetrics = new IntegerKeyStore<CharacterMetrics>(); } /** @@ -138,19 +131,17 @@ public class CharacterSetOrientation { } /** - * The first character in the character set - * @return the first character (Unicode codepoint) + * TODO */ - public char getFirstChar() { - return firstChar; + public int getUnderscoreWidth() { + return underscoreWidth; } /** - * The last character in the character set - * @return the last character (Unicode codepoint) + * TODO */ - public char getLastChar() { - return lastChar; + public int getUnderscorePosition() { + return underscorePosition; } /** @@ -162,17 +153,6 @@ public class CharacterSetOrientation { } /** - * Get the width (in 1/1000ths of a point size) of all characters - * in this character set. - * @return the widths of all characters - */ - public int[] getWidths() { - int[] arr = new int[(getLastChar() - getFirstChar()) + 1]; - System.arraycopy(charsWidths, getFirstChar(), arr, 0, (getLastChar() - getFirstChar()) + 1); - return arr; - } - - /** * XHeight refers to the height of the lower case letters above * the baseline. * @return heightX the typical height of characters @@ -187,13 +167,38 @@ public class CharacterSetOrientation { * @param character the Unicode character to evaluate * @return the widths of the character */ - public int getWidth(char character) { - if (character >= charsWidths.length) { - throw new IllegalArgumentException("Invalid character: " - + character + " (" + Integer.toString(character) - + "), maximum is " + (charsWidths.length - 1)); + public int getWidth(char character, int size) { + CharacterMetrics cm = getCharacterMetrics(character); + return cm == null ? -1 : size * cm.width; + } + + private CharacterMetrics getCharacterMetrics(char character) { + return characterMetrics.get((int) character); + } + + /** + * Get the character box (rectangle with dimensions in 1/1000ths of a point size) of the character + * identified by the parameter passed. + * @param character the Unicode character to evaluate + * @return the character box + */ + public Rectangle getCharacterBox(char character, int size) { + CharacterMetrics cm = getCharacterMetrics(character); + return scale(cm == null ? getFallbackCharacterBox() : cm.characterBox, size); + } + + private static Rectangle scale(Rectangle rectangle, int size) { + if (rectangle == null) { + return null; + } else { + return new Rectangle((int) (size * rectangle.getX()), (int) (size * rectangle.getY()), + (int) (size * rectangle.getWidth()), (int) (size * rectangle.getHeight())); } - return charsWidths[character]; + } + + private Rectangle getFallbackCharacterBox() { + // TODO replace with something sensible + return new Rectangle(0, 0, 0, 0); } /** @@ -233,19 +238,19 @@ public class CharacterSetOrientation { } /** - * The first character in the character set - * @param firstChar the first character + * TODO + * @param underscoreWidth the underscore width value in millipoints */ - public void setFirstChar(char firstChar) { - this.firstChar = firstChar; + public void setUnderscoreWidth(int underscoreWidth) { + this.underscoreWidth = underscoreWidth; } /** - * The last character in the character set - * @param lastChar the last character + * TODO + * @param underscorePosition the underscore position value in millipoints */ - public void setLastChar(char lastChar) { - this.lastChar = lastChar; + public void setUnderscorePosition(int underscorePosition) { + this.underscorePosition = underscorePosition; } /** @@ -254,17 +259,8 @@ public class CharacterSetOrientation { * @param character the Unicode character for which the width is being set * @param width the widths of the character */ - public void setWidth(char character, int width) { - if (character >= charsWidths.length) { - // Increase the size of the array if necessary - // TODO Can we remove firstChar? surely firstChar==0 at this stage? - int[] arr = new int[(character - firstChar) + 1]; - System.arraycopy(charsWidths, 0, arr, 0, charsWidths.length); - Arrays.fill(arr, charsWidths.length, character - firstChar, -1); - charsWidths = arr; - } - charsWidths[character] = width; - + public void setCharacterMetrics(char character, int width, Rectangle characterBox) { + characterMetrics.put((int) character, new CharacterMetrics(width, characterBox)); } /** @@ -299,4 +295,16 @@ public class CharacterSetOrientation { public int getNominalCharIncrement() { return this.nomCharIncrement; } + + private static class CharacterMetrics { + + public final int width; + + public final Rectangle characterBox; + + public CharacterMetrics(int width, Rectangle characterBox) { + this.width = width; + this.characterBox = characterBox; + } + } } diff --git a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java index 78da6ea82..5b9bf6101 100644 --- a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java +++ b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java @@ -19,6 +19,7 @@ package org.apache.fop.afp.fonts; +import java.awt.Rectangle; import java.lang.Character.UnicodeBlock; import java.util.HashSet; import java.util.Set; @@ -68,7 +69,7 @@ public class DoubleByteFont extends AbstractOutlineFont { public int getWidth(int character, int size) { int charWidth; try { - charWidth = charSet.getWidth(toUnicodeCodepoint(character)); + charWidth = charSet.getWidth(toUnicodeCodepoint(character), size); } catch (IllegalArgumentException e) { if (!charsProcessed.contains(character)) { charsProcessed.add(character); @@ -80,9 +81,9 @@ public class DoubleByteFont extends AbstractOutlineFont { } if (charWidth == -1) { - charWidth = getDefaultCharacterWidth(character); + charWidth = getDefaultCharacterWidth(character) * size; } - return charWidth * size; + return charWidth; } private int getDefaultCharacterWidth(int character) { @@ -94,6 +95,33 @@ public class DoubleByteFont extends AbstractOutlineFont { } } + @Override + public Rectangle getBoundingBox(int character, int size) { + Rectangle characterBox = getBoundingBoxOrNull(character, size); + if (characterBox == null) { + characterBox = getDefaultCharacterBox(character, size); + } + return characterBox; + } + + private Rectangle getBoundingBoxOrNull(int character, int size) { + Rectangle characterBox = null; + try { + characterBox = charSet.getCharacterBox(toUnicodeCodepoint(character), size); + } catch (IllegalArgumentException e) { + if (!charsProcessed.contains(character)) { + charsProcessed.add(character); + getAFPEventProducer().charactersetMissingMetrics(this, (char) character, + charSet.getName().trim()); + } + } + return characterBox; + } + + private Rectangle getDefaultCharacterBox(int character, int size) { + return getBoundingBoxOrNull('-', size); + } + private int inferCharWidth(int character) { //Is this character an ideograph? diff --git a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java index 7c2b68506..b729a8995 100644 --- a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java +++ b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java @@ -19,6 +19,8 @@ package org.apache.fop.afp.fonts; +import java.awt.Rectangle; + import org.apache.fop.afp.AFPEventProducer; import org.apache.fop.afp.util.AFPResourceAccessor; import org.apache.fop.fonts.Typeface; @@ -84,45 +86,31 @@ public class FopCharacterSet extends CharacterSet { } /** - * The first character in the character set - * @return the first character + * XHeight refers to the height of the lower case letters above the baseline. + * @return the typical height of characters */ - public char getFirstChar() { - return 0; + public int getXHeight() { + return charSet.getXHeight(1); } - /** - * The last character in the character set - * @return the last character - */ - public char getLastChar() { - return 0; + @Override + public int getWidth(char character, int size) { + return charSet.getWidth(character, size); } - /** - * Get the width (in 1/1000ths of a point size) of all characters - * @return the widths of all characters - */ - public int[] getWidths() { - return charSet.getWidths(); - } + @Override + public Rectangle getCharacterBox(char character, int size) { + return charSet.getBoundingBox(character, size); + }; - /** - * XHeight refers to the height of the lower case letters above the baseline. - * @return the typical height of characters - */ - public int getXHeight() { - return charSet.getXHeight(1); + @Override + public int getUnderscoreWidth() { + return charSet.getUnderlineThickness(1); } - /** - * Get the width (in 1/1000ths of a point size) of the character - * identified by the parameter passed. - * @param character the character from which the width will be calculated - * @return the width of the character - */ - public int getWidth(char character) { - return charSet.getWidth(character, 1); + @Override + public int getUnderscorePosition() { + return charSet.getUnderlinePosition(1); } /** diff --git a/src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java b/src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java new file mode 100644 index 000000000..7e73b5b9f --- /dev/null +++ b/src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp.fonts; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * A simple compact data structure to model a sparse array + */ +class IntegerKeyStore<T> { + + private static final int RANGE_BIT_SIZE = 8; + + private static final int RANGE_SIZE = 1 << RANGE_BIT_SIZE; + + private final Map<Integer, ArrayList<T>> arrays = new HashMap<Integer, ArrayList<T>>(); + + /** + * + * @param index a positive integer + * @param value value to store + */ + public void put(Integer index, T value) { + if (index < 0) { + throw new IndexOutOfBoundsException(); + } + int rangeKey = index >> RANGE_BIT_SIZE; + int rangeIndex = index % RANGE_SIZE; + ArrayList<T> range = arrays.get(rangeKey); + if (range == null) { + range = new ArrayList<T>(Collections.<T>nCopies(RANGE_SIZE, null)); + arrays.put(rangeKey, range); + } + range.set(rangeIndex, value); + } + + /** + * + * @param index a positive integer + * @return value the value associated with the index or null + */ + public T get(Integer index) { + if (index < 0) { + throw new IndexOutOfBoundsException(); + } + int rangeKey = index >> RANGE_BIT_SIZE; + int rangeIndex = index % RANGE_SIZE; + ArrayList<T> range = arrays.get(rangeKey); + return range == null ? null : range.get(rangeIndex); + } +} diff --git a/src/java/org/apache/fop/afp/fonts/OutlineFont.java b/src/java/org/apache/fop/afp/fonts/OutlineFont.java index e9cdf5ba4..fc2332ce9 100644 --- a/src/java/org/apache/fop/afp/fonts/OutlineFont.java +++ b/src/java/org/apache/fop/afp/fonts/OutlineFont.java @@ -19,6 +19,8 @@ package org.apache.fop.afp.fonts; +import java.awt.Rectangle; + import org.apache.fop.afp.AFPEventProducer; /** @@ -38,4 +40,18 @@ public class OutlineFont extends AbstractOutlineFont { super(name, embeddable, charSet, eventProducer); } + /** + * Obtain the width of the character for the specified point size. + * @param character the character + * @param size the font size (in mpt) + * @return the width of the character for the specified point size + */ + public int getWidth(int character, int size) { + return charSet.getWidth(toUnicodeCodepoint(character), size); + } + + @Override + public Rectangle getBoundingBox(int character, int size) { + return charSet.getCharacterBox(toUnicodeCodepoint(character), size); + } } diff --git a/src/java/org/apache/fop/afp/fonts/RasterFont.java b/src/java/org/apache/fop/afp/fonts/RasterFont.java index 5c4c38dc5..1fd30e0ba 100644 --- a/src/java/org/apache/fop/afp/fonts/RasterFont.java +++ b/src/java/org/apache/fop/afp/fonts/RasterFont.java @@ -19,8 +19,8 @@ package org.apache.fop.afp.fonts; +import java.awt.Rectangle; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; @@ -135,46 +135,21 @@ public class RasterFont extends AFPFont { } - /** - * Get the first character in this font. - * @return the first character in this font. - */ - public int getFirstChar() { - Iterator<CharacterSet> it = charSets.values().iterator(); - if (it.hasNext()) { - CharacterSet csm = it.next(); - return csm.getFirstChar(); - } else { - String msg = "getFirstChar() - No character set found for font:" + getFontName(); - LOG.error(msg); - throw new FontRuntimeException(msg); - } - } - - /** - * Get the last character in this font. - * @return the last character in this font. - */ - public int getLastChar() { - - Iterator<CharacterSet> it = charSets.values().iterator(); - if (it.hasNext()) { - CharacterSet csm = it.next(); - return csm.getLastChar(); + private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) { + int nominalVerticalSize = cs.getNominalVerticalSize(); + if (nominalVerticalSize != 0) { + return value * nominalVerticalSize; } else { - String msg = "getLastChar() - No character set found for font:" + getFontName(); - LOG.error(msg); - throw new FontRuntimeException(msg); + return value * givenSize; } - } - private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) { + private int metricsToAbsoluteSize(CharacterSet cs, double value, int givenSize) { int nominalVerticalSize = cs.getNominalVerticalSize(); if (nominalVerticalSize != 0) { - return value * nominalVerticalSize; + return (int) (value * nominalVerticalSize); } else { - return value * givenSize; + return (int) (value * givenSize); } } @@ -191,6 +166,20 @@ public class RasterFont extends AFPFont { return metricsToAbsoluteSize(cs, cs.getAscender(), size); } + /** {@inheritDoc} */ + public int getUnderlinePosition(int size) { + CharacterSet cs = getCharacterSet(size); + return metricsToAbsoluteSize(cs, cs.getUnderscorePosition(), size); + } + + @Override + public int getUnderlineThickness(int size) { + CharacterSet cs = getCharacterSet(size); + int underscoreWidth = cs.getUnderscoreWidth(); + return underscoreWidth == 0 ? super.getUnderlineThickness(size) + : metricsToAbsoluteSize(cs, underscoreWidth, size); + } + /** * Obtains the height of capital letters for the specified point size. * @@ -234,33 +223,20 @@ public class RasterFont extends AFPFont { */ public int getWidth(int character, int size) { CharacterSet cs = getCharacterSet(size); - return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character)), size); + return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character), 1), size); } /** - * Get the getWidth (in 1/1000ths of a point size) of all characters in this - * character set. - * - * @param size the font size (in mpt) - * @return the widths of all characters + * TODO */ - public int[] getWidths(int size) { + public Rectangle getBoundingBox(int character, int size) { CharacterSet cs = getCharacterSet(size); - int[] widths = cs.getWidths(); - for (int i = 0, c = widths.length; i < c; i++) { - widths[i] = metricsToAbsoluteSize(cs, widths[i], size); - } - return widths; - } - - /** - * Get the getWidth (in 1/1000ths of a point size) of all characters in this - * character set. - * - * @return the widths of all characters - */ - public int[] getWidths() { - return getWidths(1000); + Rectangle characterBox = cs.getCharacterBox(toUnicodeCodepoint(character), 1); + int x = metricsToAbsoluteSize(cs, characterBox.getX(), size); + int y = metricsToAbsoluteSize(cs, characterBox.getY(), size); + int w = metricsToAbsoluteSize(cs, characterBox.getWidth(), size); + int h = metricsToAbsoluteSize(cs, characterBox.getHeight(), size); + return new Rectangle(x, y, w, h); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java index 77ad7e806..d41adf867 100644 --- a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java +++ b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java @@ -67,7 +67,11 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord { /** {@inheritDoc} */ public int getDataLength() { - return super.getDataLength() + str.length(); + try { + return super.getDataLength() + getStringAsBytes().length; + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java b/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java index 2c6668454..5c13b9d92 100644 --- a/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java +++ b/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java @@ -25,13 +25,17 @@ import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.DocumentLoader; import org.apache.batik.bridge.UserAgent; import org.apache.batik.gvt.TextPainter; +import org.apache.batik.gvt.font.DefaultFontFamilyResolver; +import org.apache.batik.gvt.font.FontFamilyResolver; import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.fop.afp.AFPGraphics2D; +import org.apache.fop.events.EventBroadcaster; import org.apache.fop.fonts.FontInfo; import org.apache.fop.svg.AbstractFOPBridgeContext; +import org.apache.fop.svg.font.AggregatingFontFamilyResolver; /** * An AFP specific implementation of a Batik BridgeContext @@ -40,6 +44,8 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext { private final AFPGraphics2D g2d; + private final EventBroadcaster eventBroadCaster; + /** * Constructs a new bridge context. * @@ -54,47 +60,35 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext { */ public AFPBridgeContext(UserAgent userAgent, FontInfo fontInfo, ImageManager imageManager, ImageSessionContext imageSessionContext, - AffineTransform linkTransform, AFPGraphics2D g2d) { + AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) { super(userAgent, fontInfo, imageManager, imageSessionContext, linkTransform); this.g2d = g2d; + this.eventBroadCaster = eventBroadCaster; } - /** - * Constructs a new bridge context. - * @param userAgent the user agent - * @param documentLoader the Document Loader to use for referenced documents. - * @param fontInfo the font list for the text painter, may be null - * in which case text is painted as shapes - * @param imageManager an image manager - * @param imageSessionContext an image session context - * @param linkTransform AffineTransform to properly place links, - * may be null - * @param g2d an AFPGraphics 2D implementation - */ - public AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader, + private AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader, FontInfo fontInfo, ImageManager imageManager, ImageSessionContext imageSessionContext, - AffineTransform linkTransform, AFPGraphics2D g2d) { - super(userAgent, documentLoader, fontInfo, imageManager, - imageSessionContext, linkTransform); + AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) { + super(userAgent, documentLoader, fontInfo, imageManager, imageSessionContext, linkTransform); this.g2d = g2d; + this.eventBroadCaster = eventBroadCaster; } /** {@inheritDoc} */ @Override public void registerSVGBridges() { super.registerSVGBridges(); - if (fontInfo != null) { AFPTextHandler textHandler = new AFPTextHandler(fontInfo, g2d.getResourceManager()); g2d.setCustomTextHandler(textHandler); - - TextPainter textPainter = new AFPTextPainter(textHandler); - setTextPainter(textPainter); - + //TODO + FontFamilyResolver fontFamilyResolver = new AggregatingFontFamilyResolver( + new AFPFontFamilyResolver(fontInfo, eventBroadCaster), DefaultFontFamilyResolver.SINGLETON); + TextPainter textPainter = new AFPTextPainter(textHandler, fontFamilyResolver); + setTextPainter(new AFPTextPainter(textHandler, fontFamilyResolver)); putBridge(new AFPTextElementBridge(textPainter)); } - putBridge(new AFPImageElementBridge()); } @@ -105,7 +99,7 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext { fontInfo, getImageManager(), getImageSessionContext(), - linkTransform, g2d); + linkTransform, g2d, eventBroadCaster); } } diff --git a/src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java b/src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java new file mode 100644 index 000000000..a8217088b --- /dev/null +++ b/src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp.svg; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.batik.gvt.font.GVTFontFace; + +import org.apache.fop.afp.AFPEventProducer; +import org.apache.fop.afp.fonts.DoubleByteFont; +import org.apache.fop.events.EventBroadcaster; +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontTriplet; +import org.apache.fop.fonts.Typeface; +import org.apache.fop.svg.font.FOPFontFamilyResolverImpl; +import org.apache.fop.svg.font.FOPGVTFontFamily; +import org.apache.fop.svg.font.FilteringFontFamilyResolver; + +public class AFPFontFamilyResolver extends FilteringFontFamilyResolver { + + private final FontInfo fontInfo; + + private final AFPEventProducer eventProducer; + + + public AFPFontFamilyResolver(FontInfo fontInfo, EventBroadcaster eventBroadCaster) { + super(new FOPFontFamilyResolverImpl(fontInfo)); + this.fontInfo = fontInfo; + this.eventProducer = AFPEventProducer.Provider.get(eventBroadCaster); + } + + @Override + public FOPGVTFontFamily resolve(String familyName) { + FOPGVTFontFamily fopGVTFontFamily = super.resolve(familyName); + // TODO why don't DB fonts work with GOCA?!? + if (fopGVTFontFamily != null && fopGVTFontFamily.deriveFont(1, new HashMap()) + .getFont().getFontMetrics() instanceof DoubleByteFont) { + notifyDBFontRejection(fopGVTFontFamily.getFamilyName()); + fopGVTFontFamily = null; + } + return fopGVTFontFamily; + } + + @Override + public FOPGVTFontFamily getFamilyThatCanDisplay(char c) { + Map<String, Typeface> fonts = fontInfo.getFonts(); + for (Typeface font : fonts.values()) { + // TODO why don't DB fonts work with GOCA?!? + if (font.hasChar(c) && !(font instanceof DoubleByteFont)) { + String fontFamily = font.getFamilyNames().iterator().next(); + if (font instanceof DoubleByteFont) { + notifyDBFontRejection(font.getFontName()); + } else { + return new FOPGVTFontFamily(fontInfo, fontFamily, + new FontTriplet(fontFamily, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL), + new GVTFontFace(fontFamily)); + } + + } + } + return null; + } + + private void notifyDBFontRejection(String fontFamily) { + eventProducer.invalidDBFontInSVG(this, fontFamily); + } + +} diff --git a/src/java/org/apache/fop/afp/svg/AFPTextHandler.java b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java index 2bb4cb60e..e8e391bdb 100644 --- a/src/java/org/apache/fop/afp/svg/AFPTextHandler.java +++ b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java @@ -120,9 +120,8 @@ public class AFPTextHandler extends FOPTextHandlerAdapter { // set the color AFPPaintingState paintingState = g2d.getPaintingState(); - if (paintingState.setColor(color)) { - graphicsObj.setColor(color); - } + paintingState.setColor(color); + graphicsObj.setColor(color); // set the character set int fontReference = 0; @@ -135,27 +134,18 @@ public class AFPTextHandler extends FOPTextHandlerAdapter { if (log.isDebugEnabled()) { log.debug(" with overriding font: " + internalFontName + ", " + fontSize); } - } else { - java.awt.Font awtFont = g2d.getFont(); - Font fopFont = fontInfo.getFontInstanceForAWTFont(awtFont); - if (log.isDebugEnabled()) { - log.debug(" with font: " + fopFont); - } - internalFontName = fopFont.getFontName(); - fontSize = fopFont.getFontSize(); + fontSize = (int) Math.round(g2d.convertToAbsoluteLength(fontSize)); + fontReference = registerPageFont(pageFonts, internalFontName, fontSize); + // TODO: re-think above registerPageFont code... + AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName); + final CharacterSet charSet = afpFont.getCharacterSet(fontSize); + // Work-around for InfoPrint's AFP which loses character set state + // over Graphics Data + // boundaries. + graphicsObj.setCharacterSet(fontReference); + // add the character string + graphicsObj.addString(str, Math.round(x), Math.round(y), charSet); } - fontSize = (int)Math.round( - g2d.convertToAbsoluteLength(fontSize)); - fontReference = registerPageFont(pageFonts, internalFontName, fontSize); - // TODO: re-think above registerPageFont code... - AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName); - final CharacterSet charSet = afpFont.getCharacterSet(fontSize); - // Work-around for InfoPrint's AFP which loses character set state - // over Graphics Data - // boundaries. - graphicsObj.setCharacterSet(fontReference); - // add the character string - graphicsObj.addString(str, Math.round(x), Math.round(y), charSet); } else { //Inside Batik's SVG filter operations, you won't get an AFPGraphics2D g.drawString(str, x, y); diff --git a/src/java/org/apache/fop/afp/svg/AFPTextPainter.java b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java index 3815c9eae..996ae8691 100644 --- a/src/java/org/apache/fop/afp/svg/AFPTextPainter.java +++ b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java @@ -21,6 +21,9 @@ package org.apache.fop.afp.svg; import java.awt.Graphics2D; +import org.apache.batik.gvt.font.FontFamilyResolver; +import org.apache.batik.gvt.renderer.StrokingTextPainter; + import org.apache.fop.afp.AFPGraphics2D; import org.apache.fop.svg.AbstractFOPTextPainter; import org.apache.fop.svg.FOPTextHandler; @@ -39,8 +42,8 @@ public class AFPTextPainter extends AbstractFOPTextPainter { * Create a new text painter with the given font information. * @param nativeTextHandler the NativeTextHandler instance used for text painting */ - public AFPTextPainter(FOPTextHandler nativeTextHandler) { - super(nativeTextHandler); + public AFPTextPainter(FOPTextHandler nativeTextHandler, FontFamilyResolver fopFontFamilyResolver) { + super(nativeTextHandler, new FOPStrokingTextPainter(fopFontFamilyResolver)); } /** {@inheritDoc} */ @@ -48,4 +51,18 @@ public class AFPTextPainter extends AbstractFOPTextPainter { return g2d instanceof AFPGraphics2D; } + private static class FOPStrokingTextPainter extends StrokingTextPainter { + + private final FontFamilyResolver fopFontFontFamily; + + FOPStrokingTextPainter(FontFamilyResolver fopFontFontFamily) { + this.fopFontFontFamily = fopFontFontFamily; + } + + @Override + protected FontFamilyResolver getFontFamilyResolver() { + return fopFontFontFamily; + } + } + } diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java index f6de99dd0..640f04335 100644 --- a/src/java/org/apache/fop/area/AreaTreeParser.java +++ b/src/java/org/apache/fop/area/AreaTreeParser.java @@ -62,6 +62,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.area.Trait.Background; import org.apache.fop.area.Trait.InternalLink; import org.apache.fop.area.inline.AbstractTextArea; +import org.apache.fop.area.inline.Container; import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.InlineArea; @@ -195,6 +196,7 @@ public class AreaTreeParser { makers.put("space", new SpaceMaker()); makers.put("leader", new LeaderMaker()); makers.put("viewport", new InlineViewportMaker()); + makers.put("container", new ContainerMaker()); makers.put("image", new ImageMaker()); makers.put("foreignObject", new ForeignObjectMaker()); makers.put("bookmarkTree", new BookmarkTreeMaker()); @@ -863,6 +865,21 @@ public class AreaTreeParser { } } + private class ContainerMaker extends AbstractMaker { + + public void startElement(Attributes attributes) { + Container container = new Container(); + transferForeignObjects(attributes, container); + InlineViewport parent = (InlineViewport) areaStack.peek(); + parent.setContent(container); + areaStack.push(container); + } + + public void endElement() { + assertObjectOfClass(areaStack.pop(), Container.class); + } + } + private class InlineViewportMaker extends AbstractMaker { public void startElement(Attributes attributes) { diff --git a/src/java/org/apache/fop/area/inline/Container.java b/src/java/org/apache/fop/area/inline/Container.java index bc2acaa28..3d0060007 100644 --- a/src/java/org/apache/fop/area/inline/Container.java +++ b/src/java/org/apache/fop/area/inline/Container.java @@ -51,13 +51,12 @@ public class Container extends Area { public Container() { } - /** - * Add the block to this area. - * - * @param block the block area to add - */ - public void addBlock(Block block) { - blocks.add(block); + @Override + public void addChildArea(Area child) { + if (!(child instanceof Block)) { + throw new IllegalArgumentException("Container only accepts block areas"); + } + blocks.add((Block) child); } /** @@ -65,7 +64,7 @@ public class Container extends Area { * * @return the list of block areas */ - public List getBlocks() { + public List<Block> getBlocks() { return blocks; } diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java index ad8019a7d..b559e90b8 100644 --- a/src/java/org/apache/fop/cli/CommandLineOptions.java +++ b/src/java/org/apache/fop/cli/CommandLineOptions.java @@ -124,6 +124,8 @@ public class CommandLineOptions { private boolean conserveMemoryPolicy = false; /* true if a complex script features are enabled */ private boolean useComplexScriptFeatures = true; + /* set to true if -dpi used in command line */ + private boolean overrideTargetResolution = false; private FopFactory factory; private FOUserAgent foUserAgent; @@ -440,6 +442,7 @@ public class CommandLineOptions { "if you use '-dpi', you must specify a resolution (dots per inch)"); } else { this.targetResolution = Integer.parseInt(args[i + 1]); + this.overrideTargetResolution = true; return 1; } } @@ -1017,6 +1020,9 @@ public class CommandLineOptions { try { FopConfParser fopConfParser = new FopConfParser(userConfigFile, baseURI); fopFactoryBuilder = fopConfParser.getFopFactoryBuilder(); + if (this.overrideTargetResolution) { + fopFactoryBuilder.setTargetResolution(targetResolution); + } } catch (SAXException e) { throw new FOPException(e); } diff --git a/src/java/org/apache/fop/fo/FOText.java b/src/java/org/apache/fop/fo/FOText.java index 2fc998c63..0b7dde212 100644 --- a/src/java/org/apache/fop/fo/FOText.java +++ b/src/java/org/apache/fop/fo/FOText.java @@ -21,7 +21,6 @@ package org.apache.fop.fo; import java.awt.Color; import java.nio.CharBuffer; -import java.util.Map; import java.util.NoSuchElementException; import java.util.Stack; @@ -38,12 +37,13 @@ import org.apache.fop.fo.properties.CommonTextDecoration; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.Property; import org.apache.fop.fo.properties.SpaceProperty; +import org.apache.fop.fonts.TextFragment; import org.apache.fop.util.CharUtilities; /** * A text node (PCDATA) in the formatting object tree. */ -public class FOText extends FONode implements CharSequence { +public class FOText extends FONode implements CharSequence, TextFragment { /** the <code>CharBuffer</code> containing the text */ private CharBuffer charBuffer; @@ -93,9 +93,6 @@ public class FOText extends FONode implements CharSequence { /* bidi levels */ private int[] bidiLevels; - /* advanced script processing state */ - private Map/*<MapRange,String>*/ mappings; - private static final int IS_WORD_CHAR_FALSE = 0; private static final int IS_WORD_CHAR_TRUE = 1; private static final int IS_WORD_CHAR_MAYBE = 2; @@ -804,93 +801,6 @@ public class FOText extends FONode implements CharSequence { } } - /** - * Add characters mapped by script substitution processing. - * @param start index in character buffer - * @param end index in character buffer - * @param mappedChars sequence of character codes denoting substituted characters - */ - public void addMapping(int start, int end, CharSequence mappedChars) { - if (mappings == null) { - mappings = new java.util.HashMap(); - } - mappings.put(new MapRange(start, end), mappedChars.toString()); - } - - /** - * Determine if characters over specific interval have a mapping. - * @param start index in character buffer - * @param end index in character buffer - * @return true if a mapping exist such that the mapping's interval is coincident to - * [start,end) - */ - public boolean hasMapping(int start, int end) { - return (mappings != null) && (mappings.containsKey(new MapRange(start, end))); - } - - /** - * Obtain mapping of characters over specific interval. - * @param start index in character buffer - * @param end index in character buffer - * @return a string of characters representing the mapping over the interval - * [start,end) - */ - public String getMapping(int start, int end) { - if (mappings != null) { - return (String) mappings.get(new MapRange(start, end)); - } else { - return null; - } - } - - /** - * Obtain length of mapping of characters over specific interval. - * @param start index in character buffer - * @param end index in character buffer - * @return the length of the mapping (if present) or zero - */ - public int getMappingLength(int start, int end) { - if (mappings != null) { - return ((String) mappings.get(new MapRange(start, end))) .length(); - } else { - return 0; - } - } - - /** - * Obtain bidirectional levels of mapping of characters over specific interval. - * @param start index in character buffer - * @param end index in character buffer - * @return a (possibly empty) array of bidi levels or null - * in case no bidi levels have been assigned - */ - public int[] getMappingBidiLevels(int start, int end) { - if (hasMapping(start, end)) { - int nc = end - start; - int nm = getMappingLength(start, end); - int[] la = getBidiLevels(start, end); - if (la == null) { - return null; - } else if (nm == nc) { // mapping is same length as mapped range - return la; - } else if (nm > nc) { // mapping is longer than mapped range - int[] ma = new int [ nm ]; - System.arraycopy(la, 0, ma, 0, la.length); - for (int i = la.length, - n = ma.length, l = (i > 0) ? la [ i - 1 ] : 0; i < n; i++) { - ma [ i ] = l; - } - return ma; - } else { // mapping is shorter than mapped range - int[] ma = new int [ nm ]; - System.arraycopy(la, 0, ma, 0, ma.length); - return ma; - } - } else { - return getBidiLevels(start, end); - } - } - @Override protected Stack collectDelimitedTextRanges(Stack ranges, DelimitedTextRange currentRange) { if (currentRange != null) { diff --git a/src/java/org/apache/fop/fo/flow/InlineContainer.java b/src/java/org/apache/fop/fo/flow/InlineContainer.java index cf970c325..5c95fa34e 100644 --- a/src/java/org/apache/fop/fo/flow/InlineContainer.java +++ b/src/java/org/apache/fop/fo/flow/InlineContainer.java @@ -37,49 +37,38 @@ import org.apache.fop.traits.Direction; import org.apache.fop.traits.WritingMode; import org.apache.fop.traits.WritingModeTraits; -/** - * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_inline-container"> - * <code>fo:inline-container</code></a> object. - */ public class InlineContainer extends FObj { - // The value of FO traits (refined properties) that apply to fo:inline-container. - private Length alignmentAdjust; - private int alignmentBaseline; - private Length baselineShift; + private LengthRangeProperty inlineProgressionDimension; private LengthRangeProperty blockProgressionDimension; + private int overflow; private CommonBorderPaddingBackground commonBorderPaddingBackground; private CommonMarginInline commonMarginInline; - private int clip; - private int dominantBaseline; - private LengthRangeProperty inlineProgressionDimension; + private Numeric referenceOrientation; + private int displayAlign; private KeepProperty keepTogether; + private KeepProperty keepWithNext; + private KeepProperty keepWithPrevious; private SpaceProperty lineHeight; - private int overflow; - private Numeric referenceOrientation; + private Length alignmentAdjust; + private int alignmentBaseline; + private Length baselineShift; + private int dominantBaseline; private WritingModeTraits writingModeTraits; - // Unused but valid items, commented out for performance: - // private CommonRelativePosition commonRelativePosition; - // private int displayAlign; - // private Length height; - // private KeepProperty keepWithNext; - // private KeepProperty keepWithPrevious; - // private Length width; - // End of FO trait values /** used for FO validation */ - private boolean blockItemFound = false; + private boolean blockItemFound; /** - * Base constructor + * Creates a new instance. * - * @param parent {@link FONode} that is the parent of this object + * @param parent the parent of this inline-container */ public InlineContainer(FONode parent) { super(parent); } - /** {@inheritDoc} */ + @Override public void bind(PropertyList pList) throws FOPException { super.bind(pList); alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength(); @@ -88,28 +77,31 @@ public class InlineContainer extends FObj { blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange(); commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps(); commonMarginInline = pList.getMarginInlineProps(); - clip = pList.get(PR_CLIP).getEnum(); + displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum(); dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum(); inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange(); keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep(); + keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep(); + keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep(); lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); overflow = pList.get(PR_OVERFLOW).getEnum(); referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric(); writingModeTraits = new WritingModeTraits( - WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()), - pList.getExplicit(PR_WRITING_MODE) != null); + WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()), + pList.getExplicit(PR_WRITING_MODE) != null); } /** * {@inheritDoc} * <br>XSL Content Model: marker* (%block;)+ */ + @Override protected void validateChildNode(Locator loc, String nsURI, String localName) throws ValidationException { if (FO_URI.equals(nsURI)) { if (localName.equals("marker")) { if (blockItemFound) { - nodesOutOfOrderError(loc, "fo:marker", "(%block;)"); + nodesOutOfOrderError(loc, "fo:marker", "(%block;)+"); } } else if (!isBlockItem(nsURI, localName)) { invalidChildError(loc, nsURI, localName); @@ -119,153 +111,129 @@ public class InlineContainer extends FObj { } } - /** {@inheritDoc} */ + @Override public void endOfNode() throws FOPException { if (!blockItemFound) { missingChildElementError("marker* (%block;)+"); } } - /** @return the "alignment-adjust" FO trait */ - public Length getAlignmentAdjust() { - return alignmentAdjust; + /** {@inheritDoc} */ + public String getLocalName() { + return "inline-container"; } - /** @return the "alignment-baseline" FO trait */ - public int getAlignmentBaseline() { - return alignmentBaseline; + /** + * {@inheritDoc} + * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER} + */ + public int getNameId() { + return FO_INLINE_CONTAINER; } - /** @return the "baseline-shift" FO trait */ - public Length getBaselineShift() { - return baselineShift; + public LengthRangeProperty getInlineProgressionDimension() { + return inlineProgressionDimension; } - /** @return the "block-progression-dimension" FO trait */ public LengthRangeProperty getBlockProgressionDimension() { return blockProgressionDimension; } - /** @return the "clip" FO trait */ - public int getClip() { - return clip; + public int getOverflow() { + return overflow; } - /**@return Returns the {@link CommonBorderPaddingBackground} */ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() { return this.commonBorderPaddingBackground; } - /** @return Returns the {@link CommonMarginInline} */ public CommonMarginInline getCommonMarginInline() { return this.commonMarginInline; } - /** @return the "dominant-baseline" FO trait */ - public int getDominantBaseline() { - return dominantBaseline; + public int getReferenceOrientation() { + return referenceOrientation.getValue(); + } + + public int getDisplayAlign() { + return this.displayAlign; + } + + public KeepProperty getKeepWithPrevious() { + return keepWithPrevious; } - /** @return the "keep-together" FO trait */ public KeepProperty getKeepTogether() { return keepTogether; } - /** @return the "inline-progression-dimension" FO trait */ - public LengthRangeProperty getInlineProgressionDimension() { - return inlineProgressionDimension; + public KeepProperty getKeepWithNext() { + return keepWithNext; } - /** @return the "line-height" FO trait */ public SpaceProperty getLineHeight() { return lineHeight; } - /** @return the "overflow" FO trait */ - public int getOverflow() { - return overflow; + public Length getAlignmentAdjust() { + return alignmentAdjust; } - /** @return the "reference-orientation" FO trait */ - public int getReferenceOrientation() { - return referenceOrientation.getValue(); + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + public Length getBaselineShift() { + return baselineShift; + } + + public int getDominantBaseline() { + return dominantBaseline; + } + + public WritingMode getWritingMode() { + return writingModeTraits.getWritingMode(); } /** - * Obtain inline progression direction. - * @return the inline progression direction + * Obtain writing mode explicit indicator. + * @return the writing mode explicit indicator */ + public boolean getExplicitWritingMode() { + return writingModeTraits.getExplicitWritingMode(); + } + public Direction getInlineProgressionDirection() { return writingModeTraits.getInlineProgressionDirection(); } - /** - * Obtain block progression direction. - * @return the block progression direction - */ public Direction getBlockProgressionDirection() { return writingModeTraits.getBlockProgressionDirection(); } - /** - * Obtain column progression direction. - * @return the column progression direction - */ public Direction getColumnProgressionDirection() { return writingModeTraits.getColumnProgressionDirection(); } - /** - * Obtain row progression direction. - * @return the row progression direction - */ public Direction getRowProgressionDirection() { return writingModeTraits.getRowProgressionDirection(); } - /** - * Obtain (baseline) shift direction. - * @return the (baseline) shift direction - */ public Direction getShiftDirection() { return writingModeTraits.getShiftDirection(); } - /** - * Obtain writing mode. - * @return the writing mode - */ - public WritingMode getWritingMode() { - return writingModeTraits.getWritingMode(); - } - - /** - * Obtain writing mode explicit indicator. - * @return the writing mode explicit indicator - */ - public boolean getExplicitWritingMode() { - return writingModeTraits.getExplicitWritingMode(); - } - - /** {@inheritDoc} */ - public String getLocalName() { - return "inline-container"; - } - - /** - * {@inheritDoc} - * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER} - */ - public int getNameId() { - return FO_INLINE_CONTAINER; - } - @Override public boolean isDelimitedTextRangeBoundary(int boundary) { return false; } @Override + public boolean generatesReferenceAreas() { + return true; + } + + @Override protected boolean isBidiBoundary(boolean propagate) { return getExplicitWritingMode(); } diff --git a/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java index 72884a177..fe9c64cb7 100644 --- a/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java +++ b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java @@ -105,6 +105,9 @@ public class FontSizePropertyMaker // than the last caculated step lastStepFontSize = nextStepFontSize; nextStepFontSize = (int)Math.round(lastStepFontSize * scale); + if (nextStepFontSize == lastStepFontSize) { + break; + } } // baseFontSize is between last and next step font size // Return the step value closer to the baseFontSize diff --git a/src/java/org/apache/fop/fonts/Base14Font.java b/src/java/org/apache/fop/fonts/Base14Font.java index 9b2e95bc7..fdefd0cdd 100644 --- a/src/java/org/apache/fop/fonts/Base14Font.java +++ b/src/java/org/apache/fop/fonts/Base14Font.java @@ -25,4 +25,15 @@ package org.apache.fop.fonts; */ public abstract class Base14Font extends Typeface { + /** Thickness for underline and strikeout. */ + private static final int LINE_THICKNESS = 50; + + public int getStrikeoutPosition(int size) { + return getXHeight(size) / 2; + } + + public int getStrikeoutThickness(int size) { + return size * LINE_THICKNESS; + } + } diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java index 70961a55c..96b70feea 100644 --- a/src/java/org/apache/fop/fonts/CustomFont.java +++ b/src/java/org/apache/fop/fonts/CustomFont.java @@ -37,6 +37,9 @@ import org.apache.fop.apps.io.InternalResourceResolver; public abstract class CustomFont extends Typeface implements FontDescriptor, MutableFont { + /** Fallback thickness for underline and strikeout when not provided by the font. */ + private static final int DEFAULT_LINE_THICKNESS = 50; + private String fontName; private String fullName; private Set<String> familyNames; @@ -60,6 +63,14 @@ public abstract class CustomFont extends Typeface private int firstChar; private int lastChar = 255; + private int underlinePosition; + + private int underlineThickness; + + private int strikeoutPosition; + + private int strikeoutThickness; + private Map<Integer, Map<Integer, Integer>> kerning; private boolean useKerning = true; @@ -507,4 +518,40 @@ public abstract class CustomFont extends Typeface return copy; } + public int getUnderlinePosition(int size) { + return (underlinePosition == 0) + ? getDescender(size) / 2 + : size * underlinePosition; + } + + public void setUnderlinePosition(int underlinePosition) { + this.underlinePosition = underlinePosition; + } + + public int getUnderlineThickness(int size) { + return size * ((underlineThickness == 0) ? DEFAULT_LINE_THICKNESS : underlineThickness); + } + + public void setUnderlineThickness(int underlineThickness) { + this.underlineThickness = underlineThickness; + } + + public int getStrikeoutPosition(int size) { + return (strikeoutPosition == 0) + ? getXHeight(size) / 2 + : size * strikeoutPosition; + } + + public void setStrikeoutPosition(int strikeoutPosition) { + this.strikeoutPosition = strikeoutPosition; + } + + public int getStrikeoutThickness(int size) { + return (strikeoutThickness == 0) ? getUnderlineThickness(size) : size * strikeoutThickness; + } + + public void setStrikeoutThickness(int strikeoutThickness) { + this.strikeoutThickness = strikeoutThickness; + } + } diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java index 472567eec..720531205 100644 --- a/src/java/org/apache/fop/fonts/FontInfo.java +++ b/src/java/org/apache/fop/fonts/FontInfo.java @@ -30,6 +30,7 @@ import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + /** * The FontInfo holds font information for the layout and rendering of a fo document. * This stores the list of available fonts that are setup by @@ -135,12 +136,10 @@ public class FontInfo { if (oldName != null) { int oldPriority = tripletPriorities.get(triplet).intValue(); if (oldPriority < newPriority) { - logDuplicateFont(triplet, false, oldName, oldPriority, - internalFontKey, newPriority); + logDuplicateFont(triplet, false, oldName, oldPriority, internalFontKey, newPriority); return; } else { - logDuplicateFont(triplet, true, oldName, oldPriority, - internalFontKey, newPriority); + logDuplicateFont(triplet, true, oldName, oldPriority, internalFontKey, newPriority); } } this.triplets.put(triplet, internalFontKey); @@ -157,9 +156,8 @@ public class FontInfo { * @param newKey the new internal font name * @param newPriority the priority of the duplicate font mapping */ - private void logDuplicateFont(FontTriplet triplet, boolean replacing, - String oldKey, int oldPriority, - String newKey, int newPriority) { + private void logDuplicateFont(FontTriplet triplet, boolean replacing, String oldKey, int oldPriority, + String newKey, int newPriority) { if (log.isDebugEnabled()) { log.debug(triplet + (replacing ? ": Replacing " : ": Not replacing ") @@ -198,8 +196,7 @@ public class FontInfo { * default font if not found * @return internal font triplet key */ - private FontTriplet fontLookup(String family, String style, - int weight, boolean substitutable) { + private FontTriplet fontLookup(String family, String style, int weight, boolean substitutable) { if (log.isTraceEnabled()) { log.trace("Font lookup: " + family + " " + style + " " + weight + (substitutable ? " substitutable" : "")); @@ -302,8 +299,7 @@ public class FontInfo { * @return the requested Font instance */ public Font getFontInstance(FontTriplet triplet, int fontSize) { - Map<Integer, Font> sizes - = getFontInstanceCache().get(triplet); + Map<Integer, Font> sizes = getFontInstanceCache().get(triplet); if (sizes == null) { sizes = new HashMap<Integer, Font>(); getFontInstanceCache().put(triplet, sizes); @@ -379,13 +375,11 @@ public class FontInfo { * @param weight font weight * @return the font triplet of the font chosen */ - public FontTriplet fontLookup(String family, String style, - int weight) { + public FontTriplet fontLookup(String family, String style, int weight) { return fontLookup(family, style, weight, true); } - private List<FontTriplet> fontLookup(String[] families, String style, - int weight, boolean substitutable) { + private List<FontTriplet> fontLookup(String[] families, String style, int weight, boolean substitutable) { List<FontTriplet> matchingTriplets = new ArrayList<FontTriplet>(); FontTriplet triplet = null; for (int i = 0; i < families.length; i++) { @@ -410,8 +404,7 @@ public class FontInfo { * @return the set of font triplets of all supported and chosen font-families * in the specified style and weight. */ - public FontTriplet[] fontLookup(String[] families, String style, - int weight) { + public FontTriplet[] fontLookup(String[] families, String style, int weight) { if (families.length == 0) { throw new IllegalArgumentException("Specify at least one font family"); } @@ -434,8 +427,8 @@ public class FontInfo { sb.append(families[i]); } throw new IllegalStateException( - "fontLookup must return an array with at least one " - + "FontTriplet on the last call. Lookup: " + sb.toString()); + "fontLookup must return an array with at least one " + + "FontTriplet on the last call. Lookup: " + sb.toString()); } FontTriplet[] fontTriplets = new FontTriplet[matchedTriplets.size()]; @@ -469,8 +462,7 @@ public class FontInfo { * @param weight font weight * @return internal key */ - public FontTriplet findAdjustWeight(String family, String style, - int weight) { + public FontTriplet findAdjustWeight(String family, String style, int weight) { FontTriplet key = null; String f = null; int newWeight = weight; @@ -542,8 +534,7 @@ public class FontInfo { * @param weight font weight * @return internal key */ - public static FontTriplet createFontKey(String family, String style, - int weight) { + public static FontTriplet createFontKey(String family, String style, int weight) { return new FontTriplet(family, style, weight); } diff --git a/src/java/org/apache/fop/fonts/FontMetrics.java b/src/java/org/apache/fop/fonts/FontMetrics.java index ff32d7305..159d321f7 100644 --- a/src/java/org/apache/fop/fonts/FontMetrics.java +++ b/src/java/org/apache/fop/fonts/FontMetrics.java @@ -19,6 +19,7 @@ package org.apache.fop.fonts; +import java.awt.Rectangle; import java.util.Map; import java.util.Set; @@ -120,6 +121,15 @@ public interface FontMetrics { int[] getWidths(); /** + * Returns the bounding box of the glyph at the given index, for the given font size. + * + * @param glyphIndex glyph index + * @param size font size + * @return the scaled bounding box scaled in 1/1000ths of the given size + */ + Rectangle getBoundingBox(int glyphIndex, int size); + + /** * Indicates if the font has kering information. * @return True, if kerning is available. */ @@ -131,4 +141,38 @@ public interface FontMetrics { */ Map<Integer, Map<Integer, Integer>> getKerningInfo(); + /** + * Returns the distance from the baseline to the center of the underline (negative + * value indicates below baseline). + * + * @param size font size + * @return the position in 1/1000ths of the font size + */ + int getUnderlinePosition(int size); + + /** + * Returns the thickness of the underline. + * + * @param size font size + * @return the thickness in 1/1000ths of the font size + */ + int getUnderlineThickness(int size); + + /** + * Returns the distance from the baseline to the center of the strikeout line + * (negative value indicates below baseline). + * + * @param size font size + * @return the position in 1/1000ths of the font size + */ + int getStrikeoutPosition(int size); + + /** + * Returns the thickness of the strikeout line. + * + * @param size font size + * @return the thickness in 1/1000ths of the font size + */ + int getStrikeoutThickness(int size); + } diff --git a/src/java/org/apache/fop/fonts/GlyphMapping.java b/src/java/org/apache/fop/fonts/GlyphMapping.java new file mode 100644 index 000000000..a8a82085e --- /dev/null +++ b/src/java/org/apache/fop/fonts/GlyphMapping.java @@ -0,0 +1,327 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fonts; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; +import org.apache.fop.complexscripts.util.CharScript; +import org.apache.fop.traits.MinOptMax; +import org.apache.fop.util.CharUtilities; + +/** + * Stores the mapping of a text fragment to glyphs, along with various information. + */ +public class GlyphMapping { + + private static final Log LOG = LogFactory.getLog(GlyphMapping.class); + /** Inclusive. */ + public final int startIndex; + /** Exclusive. */ + public final int endIndex; + private int wordCharLength; + public final int wordSpaceCount; + public int letterSpaceCount; + public MinOptMax areaIPD; + public final boolean isHyphenated; + public final boolean isSpace; + public boolean breakOppAfter; + public final Font font; + public final int level; + public final int[][] gposAdjustments; + public final String mapping; + + public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount, + MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter, + Font font, int level, int[][] gposAdjustments) { + this(startIndex, endIndex, wordSpaceCount, letterSpaceCount, areaIPD, isHyphenated, + isSpace, breakOppAfter, font, level, gposAdjustments, null); + } + + public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount, + MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter, + Font font, int level, int[][] gposAdjustments, String mapping) { + assert startIndex <= endIndex; + this.startIndex = startIndex; + this.endIndex = endIndex; + this.wordCharLength = -1; + this.wordSpaceCount = wordSpaceCount; + this.letterSpaceCount = letterSpaceCount; + this.areaIPD = areaIPD; + this.isHyphenated = isHyphenated; + this.isSpace = isSpace; + this.breakOppAfter = breakOppAfter; + this.font = font; + this.level = level; + this.gposAdjustments = gposAdjustments; + this.mapping = mapping; + } + + public static GlyphMapping doGlyphMapping(TextFragment text, int startIndex, int endIndex, + Font font, MinOptMax letterSpaceIPD, MinOptMax[] letterSpaceAdjustArray, + char precedingChar, char breakOpportunityChar, final boolean endsWithHyphen, int level) { + GlyphMapping mapping; + if (font.performsSubstitution() || font.performsPositioning()) { + mapping = processWordMapping(text, startIndex, endIndex, font, + breakOpportunityChar, endsWithHyphen, level); + } else { + mapping = processWordNoMapping(text, startIndex, endIndex, font, + letterSpaceIPD, letterSpaceAdjustArray, precedingChar, breakOpportunityChar, endsWithHyphen, + level); + } + return mapping; + } + + private static GlyphMapping processWordMapping(TextFragment text, int startIndex, + int endIndex, final Font font, final char breakOpportunityChar, + final boolean endsWithHyphen, int level) { + int e = endIndex; // end index of word in FOText character buffer + int nLS = 0; // # of letter spaces + String script = text.getScript(); + String language = text.getLanguage(); + + if (LOG.isDebugEnabled()) { + LOG.debug("PW: [" + startIndex + "," + endIndex + "]: {" + + " +M" + + ", level = " + level + + " }"); + } + + // 1. extract unmapped character sequence + CharSequence ics = text.subSequence(startIndex, e); + + // 2. if script is not specified (by FO property) or it is specified as 'auto', + // then compute dominant script + if ((script == null) || "auto".equals(script)) { + script = CharScript.scriptTagFromCode(CharScript.dominantScript(ics)); + } + if ((language == null) || "none".equals(language)) { + language = "dflt"; + } + + // 3. perform mapping of chars to glyphs ... to glyphs ... to chars + CharSequence mcs = font.performSubstitution(ics, script, language); + + // 4. compute glyph position adjustments on (substituted) characters + int[][] gpa; + if (font.performsPositioning()) { + // handle GPOS adjustments + gpa = font.performPositioning(mcs, script, language); + } else if (font.hasKerning()) { + // handle standard (non-GPOS) kerning adjustments + gpa = getKerningAdjustments(mcs, font); + } else { + gpa = null; + } + + // 5. reorder combining marks so that they precede (within the mapped char sequence) the + // base to which they are applied; N.B. position adjustments (gpa) are reordered in place + mcs = font.reorderCombiningMarks(mcs, gpa, script, language); + + // 6. compute word ipd based on final position adjustments + MinOptMax ipd = MinOptMax.ZERO; + for (int i = 0, n = mcs.length(); i < n; i++) { + int c = mcs.charAt(i); + // TODO !BMP + int w = font.getCharWidth(c); + if (w < 0) { + w = 0; + } + if (gpa != null) { + w += gpa[i][GlyphPositioningTable.Value.IDX_X_ADVANCE]; + } + ipd = ipd.plus(w); + } + + // [TBD] - handle letter spacing + + return new GlyphMapping(startIndex, e, 0, nLS, ipd, endsWithHyphen, false, + breakOpportunityChar != 0, font, level, gpa, + CharUtilities.isSameSequence(mcs, ics) ? null : mcs.toString()); + } + + /** + * Given a mapped character sequence MCS, obtain glyph position adjustments from the + * font's kerning data. + * + * @param mcs mapped character sequence + * @param font applicable font + * @return glyph position adjustments (or null if no kerning) + */ + private static int[][] getKerningAdjustments(CharSequence mcs, final Font font) { + int nc = mcs.length(); + // extract kerning array + int[] ka = new int[nc]; // kerning array + for (int i = 0, n = nc, cPrev = -1; i < n; i++) { + int c = mcs.charAt(i); + // TODO !BMP + if (cPrev >= 0) { + ka[i] = font.getKernValue(cPrev, c); + } + cPrev = c; + } + // was there a non-zero kerning? + boolean hasKerning = false; + for (int i = 0, n = nc; i < n; i++) { + if (ka[i] != 0) { + hasKerning = true; + break; + } + } + // if non-zero kerning, then create and return glyph position adjustment array + if (hasKerning) { + int[][] gpa = new int[nc][4]; + for (int i = 0, n = nc; i < n; i++) { + if (i > 0) { + gpa [i - 1][GlyphPositioningTable.Value.IDX_X_ADVANCE] = ka[i]; + } + } + return gpa; + } else { + return null; + } + } + + private static GlyphMapping processWordNoMapping(TextFragment text, int startIndex, int endIndex, + final Font font, MinOptMax letterSpaceIPD, MinOptMax[] letterSpaceAdjustArray, + char precedingChar, final char breakOpportunityChar, final boolean endsWithHyphen, int level) { + boolean kerning = font.hasKerning(); + MinOptMax wordIPD = MinOptMax.ZERO; + + if (LOG.isDebugEnabled()) { + LOG.debug("PW: [" + startIndex + "," + endIndex + "]: {" + + " -M" + + ", level = " + level + + " }"); + } + + for (int i = startIndex; i < endIndex; i++) { + char currentChar = text.charAt(i); + + // character width + int charWidth = font.getCharWidth(currentChar); + wordIPD = wordIPD.plus(charWidth); + + // kerning + if (kerning) { + int kern = 0; + if (i > startIndex) { + char previousChar = text.charAt(i - 1); + kern = font.getKernValue(previousChar, currentChar); + } else if (precedingChar != 0) { + kern = font.getKernValue(precedingChar, currentChar); + } + if (kern != 0) { + addToLetterAdjust(letterSpaceAdjustArray, i, kern); + wordIPD = wordIPD.plus(kern); + } + } + } + if (kerning + && (breakOpportunityChar != 0) + && !isSpace(breakOpportunityChar) + && endIndex > 0 + && endsWithHyphen) { + int kern = font.getKernValue(text.charAt(endIndex - 1), breakOpportunityChar); + if (kern != 0) { + addToLetterAdjust(letterSpaceAdjustArray, endIndex, kern); + // TODO: add kern to wordIPD? + } + } + // shy+chars at start of word: wordLength == 0 && breakOpportunity + // shy only characters in word: wordLength == 0 && !breakOpportunity + int wordLength = endIndex - startIndex; + int letterSpaces = 0; + if (wordLength != 0) { + letterSpaces = wordLength - 1; + // if there is a break opportunity and the next one (break character) + // is not a space, it could be used as a line end; + // add one more letter space, in case other text follows + if ((breakOpportunityChar != 0) && !isSpace(breakOpportunityChar)) { + letterSpaces++; + } + } + assert letterSpaces >= 0; + wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces)); + + // create and return the AreaInfo object + return new GlyphMapping(startIndex, endIndex, 0, + letterSpaces, wordIPD, + endsWithHyphen, + false, breakOpportunityChar != 0, font, level, null); + } + + private static void addToLetterAdjust(MinOptMax[] letterSpaceAdjustArray, int index, int width) { + if (letterSpaceAdjustArray[index] == null) { + letterSpaceAdjustArray[index] = MinOptMax.getInstance(width); + } else { + letterSpaceAdjustArray[index] = letterSpaceAdjustArray[index].plus(width); + } + } + + /** + * Indicates whether a character is a space in terms of this layout manager. + * + * @param ch the character + * @return true if it's a space + */ + public static boolean isSpace(final char ch) { + return ch == CharUtilities.SPACE + || CharUtilities.isNonBreakableSpace(ch) + || CharUtilities.isFixedWidthSpace(ch); + } + + /** + * Obtain number of 'characters' contained in word. If word is mapped, then this + * number may be less than or greater than the original length (breakIndex - + * startIndex). We compute and memoize thius length upon first invocation of this + * method. + */ + public int getWordLength() { + if (wordCharLength == -1) { + if (mapping != null) { + wordCharLength = mapping.length(); + } else { + assert endIndex >= startIndex; + wordCharLength = endIndex - startIndex; + } + } + return wordCharLength; + } + + public void addToAreaIPD(MinOptMax idp) { + areaIPD = areaIPD.plus(idp); + } + + public String toString() { + return super.toString() + "{" + + "interval = [" + startIndex + "," + endIndex + "]" + + ", isSpace = " + isSpace + + ", level = " + level + + ", areaIPD = " + areaIPD + + ", letterSpaceCount = " + letterSpaceCount + + ", wordSpaceCount = " + wordSpaceCount + + ", isHyphenated = " + isHyphenated + + ", font = " + font + + "}"; + } + +} diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java index 49b2e0457..1877a895e 100644 --- a/src/java/org/apache/fop/fonts/LazyFont.java +++ b/src/java/org/apache/fop/fonts/LazyFont.java @@ -18,6 +18,7 @@ /* $Id$ */ package org.apache.fop.fonts; +import java.awt.Rectangle; import java.io.IOException; import java.io.InputStream; import java.net.URI; @@ -250,6 +251,26 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable, return realFont.getXHeight(size); } + public int getUnderlinePosition(int size) { + load(true); + return realFont.getUnderlinePosition(size); + } + + public int getUnderlineThickness(int size) { + load(true); + return realFont.getUnderlineThickness(size); + } + + public int getStrikeoutPosition(int size) { + load(true); + return realFont.getStrikeoutPosition(size); + } + + public int getStrikeoutThickness(int size) { + load(true); + return realFont.getStrikeoutThickness(size); + } + /** * {@inheritDoc} */ @@ -268,6 +289,11 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable, return realFont.getWidths(); } + public Rectangle getBoundingBox(int glyphIndex, int size) { + load(true); + return realFont.getBoundingBox(glyphIndex, size); + } + /** * {@inheritDoc} */ diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java index 68be7bed8..cc3d06650 100644 --- a/src/java/org/apache/fop/fonts/MultiByteFont.java +++ b/src/java/org/apache/fop/fonts/MultiByteFont.java @@ -19,6 +19,7 @@ package org.apache.fop.fonts; +import java.awt.Rectangle; import java.nio.CharBuffer; import java.nio.IntBuffer; import java.util.BitSet; @@ -68,6 +69,9 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl private int firstUnmapped; private int lastUnmapped; + /** Contains the character bounding boxes for all characters in the font */ + protected Rectangle[] boundingBoxes; + private boolean isOTFFile = false; // since for most users the most likely glyphs are in the first cmap segments we store their mapping. @@ -196,6 +200,12 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl return arr; } + public Rectangle getBoundingBox(int glyphIndex, int size) { + int index = isEmbeddable() ? cidSet.getOriginalGlyphIndex(glyphIndex) : glyphIndex; + Rectangle bbox = boundingBoxes[index]; + return new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size); + } + /** * Returns the glyph index for a Unicode character. The method returns 0 if there's no * such glyph in the character map. @@ -401,6 +411,14 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl } /** + * Sets the bounding boxes array. + * @param boundingBoxes array of bounding boxes. + */ + public void setBBoxArray(Rectangle[] boundingBoxes) { + this.boundingBoxes = boundingBoxes; + } + + /** * Returns a Map of used Glyphs. * @return Map Map of used Glyphs */ diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java index a61d846e6..2a6b04761 100644 --- a/src/java/org/apache/fop/fonts/SingleByteFont.java +++ b/src/java/org/apache/fop/fonts/SingleByteFont.java @@ -19,6 +19,7 @@ package org.apache.fop.fonts; +import java.awt.Rectangle; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -47,6 +48,8 @@ public class SingleByteFont extends CustomFont { private int[] width = null; + private Rectangle[] boundingBoxes; + private Map<Character, UnencodedCharacter> unencodedCharacters; private List<SimpleSingleByteEncoding> additionalEncodings; private Map<Character, Character> alternativeCodes; @@ -111,6 +114,24 @@ public class SingleByteFont extends CustomFont { return arr; } + public Rectangle getBoundingBox(int glyphIndex, int size) { + Rectangle bbox = null; + if (glyphIndex < 256) { + int idx = glyphIndex - getFirstChar(); + if (idx >= 0 && idx < boundingBoxes.length) { + bbox = boundingBoxes[idx]; + } + } else if (this.additionalEncodings != null) { + int encodingIndex = (glyphIndex / 256) - 1; + SimpleSingleByteEncoding encoding = getAdditionalEncoding(encodingIndex); + int codePoint = glyphIndex % 256; + NamedCharacter nc = encoding.getCharacterForIndex(codePoint); + UnencodedCharacter uc = this.unencodedCharacters.get(Character.valueOf(nc.getSingleUnicodeValue())); + bbox = uc.getBBox(); + } + return bbox == null ? null : new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size); + } + /** * Lookup a character using its alternative names. If found, cache it so we * can speed up lookups. @@ -292,17 +313,24 @@ public class SingleByteFont extends CustomFont { this.width[index - getFirstChar()] = w; } + public void setBoundingBox(int index, Rectangle bbox) { + if (this.boundingBoxes == null) { + this.boundingBoxes = new Rectangle[getLastChar() - getFirstChar() + 1]; + } + this.boundingBoxes[index - getFirstChar()] = bbox; + } + /** * Adds an unencoded character (one that is not supported by the primary encoding). * @param ch the named character * @param width the width of the character */ - public void addUnencodedCharacter(NamedCharacter ch, int width) { + public void addUnencodedCharacter(NamedCharacter ch, int width, Rectangle bbox) { if (this.unencodedCharacters == null) { this.unencodedCharacters = new HashMap<Character, UnencodedCharacter>(); } if (ch.hasSingleUnicodeValue()) { - UnencodedCharacter uc = new UnencodedCharacter(ch, width); + UnencodedCharacter uc = new UnencodedCharacter(ch, width, bbox); this.unencodedCharacters.put(Character.valueOf(ch.getSingleUnicodeValue()), uc); } else { //Cannot deal with unicode sequences, so ignore this character @@ -381,10 +409,12 @@ public class SingleByteFont extends CustomFont { private final NamedCharacter character; private final int width; + private final Rectangle bbox; - public UnencodedCharacter(NamedCharacter character, int width) { + public UnencodedCharacter(NamedCharacter character, int width, Rectangle bbox) { this.character = character; this.width = width; + this.bbox = bbox; } public NamedCharacter getCharacter() { @@ -395,6 +425,10 @@ public class SingleByteFont extends CustomFont { return this.width; } + public Rectangle getBBox() { + return bbox; + } + /** {@inheritDoc} */ @Override public String toString() { diff --git a/src/java/org/apache/fop/fonts/TextFragment.java b/src/java/org/apache/fop/fonts/TextFragment.java new file mode 100644 index 000000000..ad72db8e0 --- /dev/null +++ b/src/java/org/apache/fop/fonts/TextFragment.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fonts; + +public interface TextFragment { + + String getScript(); + + String getLanguage(); + + char charAt(int index); + + CharSequence subSequence(int startIndex, int endIndex); +} diff --git a/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java b/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java index f15837bb8..7168389ff 100644 --- a/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java +++ b/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java @@ -19,6 +19,7 @@ package org.apache.fop.fonts.truetype; +import java.awt.Rectangle; import java.io.IOException; import java.io.InputStream; import java.net.URI; @@ -149,6 +150,10 @@ public class OFFontLoader extends FontLoader { returnFont.setAscender(otf.getLowerCaseAscent()); returnFont.setDescender(otf.getLowerCaseDescent()); returnFont.setFontBBox(otf.getFontBBox()); + returnFont.setUnderlinePosition(otf.getUnderlinePosition() - otf.getUnderlineThickness() / 2); + returnFont.setUnderlineThickness(otf.getUnderlineThickness()); + returnFont.setStrikeoutPosition(otf.getStrikeoutPosition() - otf.getStrikeoutThickness() / 2); + returnFont.setStrikeoutThickness(otf.getStrikeoutThickness()); returnFont.setFlags(otf.getFlags()); returnFont.setStemV(Integer.parseInt(otf.getStemV())); //not used for TTF returnFont.setItalicAngle(Integer.parseInt(otf.getItalicAngle())); @@ -161,15 +166,15 @@ public class OFFontLoader extends FontLoader { } else { multiFont.setCIDType(CIDFontType.CIDTYPE2); } - int[] wx = otf.getWidths(); - multiFont.setWidthArray(wx); + multiFont.setWidthArray(otf.getWidths()); + multiFont.setBBoxArray(otf.getBoundingBoxes()); } else { singleFont.setFontType(FontType.TRUETYPE); singleFont.setEncoding(otf.getCharSetName()); returnFont.setFirstChar(otf.getFirstChar()); returnFont.setLastChar(otf.getLastChar()); singleFont.setTrueTypePostScriptVersion(otf.getPostScriptVersion()); - copyWidthsSingleByte(otf); + copyGlyphMetricsSingleByte(otf); } returnFont.setCMap(getCMap(otf)); @@ -195,10 +200,14 @@ public class OFFontLoader extends FontLoader { return otf.getCMaps().toArray(array); } - private void copyWidthsSingleByte(OpenFont otf) { + private void copyGlyphMetricsSingleByte(OpenFont otf) { int[] wx = otf.getWidths(); + Rectangle[] bboxes = otf.getBoundingBoxes(); for (int i = singleFont.getFirstChar(); i <= singleFont.getLastChar(); i++) { singleFont.setWidth(i, otf.getCharWidth(i)); + int[] bbox = otf.getBBox(i); + singleFont.setBoundingBox(i, + new Rectangle(bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1])); } for (CMapSegment segment : otf.getCMaps()) { @@ -214,7 +223,7 @@ public class OFFontLoader extends FontLoader { if (glyphName.length() > 0) { String unicode = Character.toString(u); NamedCharacter nc = new NamedCharacter(glyphName, unicode); - singleFont.addUnencodedCharacter(nc, wx[glyphIndex]); + singleFont.addUnencodedCharacter(nc, wx[glyphIndex], bboxes[glyphIndex]); } } } diff --git a/src/java/org/apache/fop/fonts/truetype/OTFFile.java b/src/java/org/apache/fop/fonts/truetype/OTFFile.java index 3976b5994..ab9654beb 100644 --- a/src/java/org/apache/fop/fonts/truetype/OTFFile.java +++ b/src/java/org/apache/fop/fonts/truetype/OTFFile.java @@ -20,11 +20,17 @@ package org.apache.fop.fonts.truetype; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import org.apache.fontbox.cff.CFFDataInput; import org.apache.fontbox.cff.CFFFont; -import org.apache.fontbox.cff.CFFFont.Mapping; import org.apache.fontbox.cff.CFFParser; +import org.apache.fontbox.cff.charset.CFFCharset; public class OTFFile extends OpenFont { @@ -45,17 +51,77 @@ public class OTFFile extends OpenFont { @Override protected void updateBBoxAndOffset() throws IOException { + List<Mapping> gidMappings = getGIDMappings(fileFont); + Map<Integer, String> sidNames = constructNameMap(gidMappings); UnicodeMapping[] mappings = unicodeMappings.toArray(new UnicodeMapping[0]); for (int i = 0; i < mappings.length; i++) { int glyphIdx = mappings[i].getGlyphIndex(); - Mapping m = fileFont.getGIDMappings().get(glyphIdx); - int[] bbox = fileFont.getBoundingBox(m.getSID()); - String name = fileFont.getNameOfCharFromCode(m.getSID()); - mtxTab[glyphIdx].setBoundingBox(bbox); + Mapping m = gidMappings.get(glyphIdx); + String name = sidNames.get(m.getSID()); mtxTab[glyphIdx].setName(name); } } + private List<Mapping> getGIDMappings(CFFFont font) { + List<Mapping> gidMappings = new ArrayList<Mapping>(); + Mapping notdef = new Mapping(); + gidMappings.add(notdef); + for (CFFCharset.Entry entry : font.getCharset().getEntries()) { + String name = entry.getName(); + byte[] bytes = font.getCharStringsDict().get(name); + if (bytes == null) { + continue; + } + Mapping mapping = new Mapping(); + mapping.setSID(entry.getSID()); + mapping.setName(name); + mapping.setBytes(bytes); + gidMappings.add(mapping); + } + return gidMappings; + } + + private Map<Integer, String> constructNameMap(Collection<Mapping> mappings) { + Map<Integer, String> sidNames = new HashMap<Integer, String>(); + Iterator<Mapping> it = mappings.iterator(); + while (it.hasNext()) { + Mapping mapping = it.next(); + sidNames.put(mapping.getSID(), mapping.getName()); + } + return sidNames; + } + + private static class Mapping { + private int sid; + private String name; + private byte[] bytes; + + public void setSID(int sid) { + this.sid = sid; + } + + public int getSID() { + return sid; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + public byte[] getBytes() { + return bytes; + } + } + + @Override protected void initializeFont(FontFileReader in) throws IOException { fontFile = in; diff --git a/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java b/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java index 4d0cce67a..9cb3458c8 100644 --- a/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java +++ b/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java @@ -861,7 +861,6 @@ public class OTFSubSetFile extends OTFFile { return hdrTotal + total; } - private BytesNumber readNumber(int b0, byte[] input, int curPos) throws IOException { if (b0 == 28) { int b1 = input[curPos + 1] & 0xff; @@ -887,7 +886,7 @@ public class OTFSubSetFile extends OTFFile { /** * A class used to store the last number operand and also it's size in bytes */ - private static final class BytesNumber { + static class BytesNumber { private int number; private int numBytes; @@ -908,6 +907,26 @@ public class OTFSubSetFile extends OTFFile { this.number = -1; this.numBytes = -1; } + + public String toString() { + return Integer.toString(number); + } + + @Override + public boolean equals(Object entry) { + assert entry instanceof BytesNumber; + BytesNumber bnEntry = (BytesNumber)entry; + return this.number == bnEntry.getNumber() + && this.numBytes == bnEntry.getNumBytes(); + } + + @Override + public int hashCode() { + int hash = 1; + hash = hash * 17 + number; + hash = hash * 31 + numBytes; + return hash; + } } private void writeCharsetTable(boolean cidFont) throws IOException { @@ -1094,4 +1113,12 @@ public class OTFSubSetFile extends OTFFile { System.arraycopy(output, 0, ret, 0, realSize); return ret; } + + /** + * Returns the parsed CFF data for the original font. + * @return The CFFDataReader contaiing the parsed data + */ + public CFFDataReader getCFFReader() { + return cffReader; + } } diff --git a/src/java/org/apache/fop/fonts/truetype/OpenFont.java b/src/java/org/apache/fop/fonts/truetype/OpenFont.java index ce9a2b388..3f4765cdc 100644 --- a/src/java/org/apache/fop/fonts/truetype/OpenFont.java +++ b/src/java/org/apache/fop/fonts/truetype/OpenFont.java @@ -19,6 +19,7 @@ package org.apache.fop.fonts.truetype; +import java.awt.Rectangle; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -195,6 +196,10 @@ public abstract class OpenFont { private int fontBBox4 = 0; private int capHeight = 0; private int os2CapHeight = 0; + private int underlinePosition; + private int underlineThickness; + private int strikeoutPosition; + private int strikeoutThickness; private int xHeight = 0; private int os2xHeight = 0; //Effective ascender/descender @@ -995,10 +1000,22 @@ public abstract class OpenFont { for (int i = 0; i < wx.length; i++) { wx[i] = convertTTFUnit2PDFUnit(mtxTab[i].getWx()); } - return wx; } + public Rectangle[] getBoundingBoxes() { + Rectangle[] boundingBoxes = new Rectangle[mtxTab.length]; + for (int i = 0; i < boundingBoxes.length; i++) { + int[] boundingBox = mtxTab[i].getBoundingBox(); + boundingBoxes[i] = new Rectangle( + convertTTFUnit2PDFUnit(boundingBox[0]), + convertTTFUnit2PDFUnit(boundingBox[1]), + convertTTFUnit2PDFUnit(boundingBox[2] - boundingBox[0]), + convertTTFUnit2PDFUnit(boundingBox[3] - boundingBox[1])); + } + return boundingBoxes; + } + /** * Returns an array (xMin, yMin, xMax, yMax) for a glyph. * @@ -1039,6 +1056,22 @@ public abstract class OpenFont { return ansiKerningTab; } + public int getUnderlinePosition() { + return convertTTFUnit2PDFUnit(underlinePosition); + } + + public int getUnderlineThickness() { + return convertTTFUnit2PDFUnit(underlineThickness); + } + + public int getStrikeoutPosition() { + return convertTTFUnit2PDFUnit(strikeoutPosition); + } + + public int getStrikeoutThickness() { + return convertTTFUnit2PDFUnit(strikeoutThickness); + } + /** * Indicates if the font may be embedded. * @return boolean True if it may be embedded @@ -1215,10 +1248,8 @@ public abstract class OpenFont { seekTab(fontFile, OFTableName.POST, 0); int postFormat = fontFile.readTTFLong(); italicAngle = fontFile.readTTFULong(); - //underlinePosition - fontFile.readTTFShort(); - //underlineThickness - fontFile.readTTFShort(); + underlinePosition = fontFile.readTTFShort(); + underlineThickness = fontFile.readTTFShort(); isFixedPitch = fontFile.readTTFULong(); //Skip memory usage values @@ -1322,7 +1353,10 @@ public abstract class OpenFont { } else { isEmbeddable = true; } - fontFile.skip(11 * 2); + fontFile.skip(8 * 2); + strikeoutThickness = fontFile.readTTFShort(); + strikeoutPosition = fontFile.readTTFShort(); + fontFile.skip(2); fontFile.skip(10); //panose array fontFile.skip(4 * 4); //unicode ranges fontFile.skip(4); diff --git a/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java b/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java index 4906f2c31..8d9f4238b 100644 --- a/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java +++ b/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java @@ -19,7 +19,7 @@ package org.apache.fop.fonts.type1; -import java.awt.geom.RectangularShape; +import java.awt.Rectangle; import org.apache.fop.fonts.NamedCharacter; @@ -33,7 +33,7 @@ public class AFMCharMetrics { private NamedCharacter character; private double widthX; private double widthY; - private RectangularShape bBox; + private Rectangle bBox; /** * Returns the character code. @@ -137,7 +137,7 @@ public class AFMCharMetrics { * Returns the character's bounding box. * @return the bounding box (or null if it isn't available) */ - public RectangularShape getBBox() { + public Rectangle getBBox() { return bBox; } @@ -145,7 +145,7 @@ public class AFMCharMetrics { * Sets the character's bounding box. * @param box the bounding box */ - public void setBBox(RectangularShape box) { + public void setBBox(Rectangle box) { bBox = box; } diff --git a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java index 716faa61e..260ef209f 100644 --- a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java +++ b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java @@ -217,12 +217,16 @@ public class Type1FontLoader extends FontLoader { for (AFMCharMetrics metrics : charMetrics) { String charName = metrics.getCharName(); if (charName != null && !glyphNames.contains(charName)) { - singleFont.addUnencodedCharacter(metrics.getCharacter(), - (int)Math.round(metrics.getWidthX())); + addUnencodedCharacter(singleFont, metrics); } } } + private static void addUnencodedCharacter(SingleByteFont font, AFMCharMetrics metrics) { + font.addUnencodedCharacter(metrics.getCharacter(), + (int) Math.round(metrics.getWidthX()), metrics.getBBox()); + } + /** * Adds characters not encoded in the font's primary encoding. This method is used when * the primary encoding is built based on the character codes in the AFM rather than @@ -234,8 +238,7 @@ public class Type1FontLoader extends FontLoader { for (int i = 0, c = afm.getCharCount(); i < c; i++) { AFMCharMetrics metrics = (AFMCharMetrics)charMetrics.get(i); if (!metrics.hasCharCode() && metrics.getCharacter() != null) { - singleFont.addUnencodedCharacter(metrics.getCharacter(), - (int)Math.round(metrics.getWidthX())); + addUnencodedCharacter(singleFont, metrics); } } } @@ -281,7 +284,10 @@ public class Type1FontLoader extends FontLoader { } else { returnFont.setStemV(80); // Arbitrary value } - returnFont.setItalicAngle((int) afm.getWritingDirectionMetrics(0).getItalicAngle()); + AFMWritingDirectionMetrics metrics = afm.getWritingDirectionMetrics(0); + returnFont.setItalicAngle((int) metrics.getItalicAngle()); + returnFont.setUnderlinePosition(metrics.getUnderlinePosition().intValue()); + returnFont.setUnderlineThickness(metrics.getUnderlineThickness().intValue()); } else { returnFont.setFontBBox(pfm.getFontBBox()); returnFont.setStemV(pfm.getStemV()); @@ -383,6 +389,7 @@ public class Type1FontLoader extends FontLoader { for (AFMCharMetrics chm : afm.getCharMetrics()) { if (chm.hasCharCode()) { singleFont.setWidth(chm.getCharCode(), (int) Math.round(chm.getWidthX())); + singleFont.setBoundingBox(chm.getCharCode(), chm.getBBox()); } } if (useKerning) { diff --git a/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java b/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java index 79592efd1..ec187b8d0 100644 --- a/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java +++ b/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java @@ -33,6 +33,7 @@ import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.bridge.UserAgent; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.gvt.GraphicsNode; +import org.apache.batik.gvt.font.DefaultFontFamilyResolver; import org.apache.xmlgraphics.image.GraphicsConstants; import org.apache.xmlgraphics.image.loader.Image; @@ -123,10 +124,8 @@ public class ImageConverterSVG2G2D extends AbstractImageConverter { * @return the newly created user agent */ protected SimpleSVGUserAgent createBatikUserAgent(float pxToMillimeter) { - return new SimpleSVGUserAgent( - pxToMillimeter, - new AffineTransform()) { - + return new SimpleSVGUserAgent(pxToMillimeter, new AffineTransform(), + DefaultFontFamilyResolver.SINGLETON) { /** {@inheritDoc} */ public void displayMessage(String message) { //TODO Refine and pipe through to caller diff --git a/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java b/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java index 3aa340a4a..58daadc52 100644 --- a/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java +++ b/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java @@ -38,6 +38,7 @@ import org.apache.batik.bridge.UnitProcessor; import org.apache.batik.bridge.UserAgent; import org.apache.batik.dom.svg.SAXSVGDocumentFactory; import org.apache.batik.dom.svg.SVGOMDocument; +import org.apache.batik.gvt.font.DefaultFontFamilyResolver; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageInfo; @@ -162,7 +163,7 @@ public class PreloaderSVG extends AbstractImagePreloader { Element e = doc.getRootElement(); float pxUnitToMillimeter = UnitConv.IN2MM / context.getSourceResolution(); UserAgent userAg = new SimpleSVGUserAgent(pxUnitToMillimeter, - new AffineTransform()) { + new AffineTransform(), DefaultFontFamilyResolver.SINGLETON) { /** {@inheritDoc} */ public void displayMessage(String message) { diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java index 5d7cc0b64..635e267c1 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java @@ -65,9 +65,6 @@ public abstract class AbstractBaseLayoutManager public AbstractBaseLayoutManager(FObj fo) { this.fobj = fo; setGeneratesReferenceArea(fo.generatesReferenceAreas()); - if (getGeneratesReferenceArea()) { - setGeneratesBlockArea(true); - } } // --------- Property Resolution related functions --------- // diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java index 0285a41e7..2dd18e4ee 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -342,6 +342,34 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager im && isFinished()); } + public boolean hasLineAreaDescendant() { + if (childLMs == null || childLMs.isEmpty()) { + return false; + } else { + for (LayoutManager childLM : childLMs) { + if (childLM.hasLineAreaDescendant()) { + return true; + } + } + } + return false; + } + + public int getBaselineOffset() { + if (childLMs != null) { + for (LayoutManager childLM : childLMs) { + if (childLM.hasLineAreaDescendant()) { + return childLM.getBaselineOffset(); + } + } + } + throw newNoLineAreaDescendantException(); + } + + protected IllegalStateException newNoLineAreaDescendantException() { + return new IllegalStateException("getBaselineOffset called on an object that has no line-area descendant"); + } + /** * Transfers foreign attributes from the formatting object to the area. * @param targetArea the area to set the attributes on diff --git a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java index 0ed6cb69b..d731ab62a 100644 --- a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java +++ b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java @@ -33,11 +33,11 @@ public final class AreaAdditionUtil { /** * Creates the child areas for the given layout manager. - * @param bslm the BlockStackingLayoutManager instance for which "addAreas" is performed. + * @param parentLM the parent layout manager * @param parentIter the position iterator * @param layoutContext the layout context */ - public static void addAreas(BlockStackingLayoutManager bslm, + public static void addAreas(AbstractLayoutManager parentLM, PositionIterator parentIter, LayoutContext layoutContext) { LayoutManager childLM; LayoutContext lc = LayoutContext.offspringOf(layoutContext); @@ -46,8 +46,8 @@ public final class AreaAdditionUtil { Position firstPos = null; Position lastPos = null; - if (bslm != null) { - bslm.addId(); + if (parentLM != null) { + parentLM.addId(); } // "unwrap" the NonLeafPositions stored in parentIter @@ -86,11 +86,11 @@ public final class AreaAdditionUtil { //doesn't give us that info. } - if (bslm != null) { - bslm.registerMarkers( + if (parentLM != null) { + parentLM.registerMarkers( true, - bslm.isFirst(firstPos), - bslm.isLast(lastPos)); + parentLM.isFirst(firstPos), + parentLM.isLast(lastPos)); } PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); @@ -113,11 +113,11 @@ public final class AreaAdditionUtil { childLM.addAreas(childPosIter, lc); } - if (bslm != null) { - bslm.registerMarkers( + if (parentLM != null) { + parentLM.registerMarkers( false, - bslm.isFirst(firstPos), - bslm.isLast(lastPos)); + parentLM.isFirst(firstPos), + parentLM.isLast(lastPos)); } diff --git a/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java b/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java index b5b712a33..c59c9d607 100644 --- a/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java +++ b/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java @@ -20,12 +20,11 @@ package org.apache.fop.layoutmgr; import java.util.LinkedList; import java.util.List; -import org.apache.fop.fo.flow.MultiSwitch; import org.apache.fop.layoutmgr.BestFitPenalty.Variant; /** * Utility class used in {@link MultiSwitchLayoutManager} - * to handle the <i>best-fit</i> property value if specified in {@link MultiSwitch} + * to handle the <i>best-fit</i> property value if specified in {@link org.apache.fop.fo.flow.MultiSwitch} */ public final class BestFitLayoutUtils { diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index eced48939..3da6974a6 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -37,6 +37,7 @@ import org.apache.fop.datatypes.FODimension; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.flow.BlockContainer; import org.apache.fop.fo.properties.CommonAbsolutePosition; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal; /** * LayoutManager for a block-container FO. */ -public class BlockContainerLayoutManager extends BlockStackingLayoutManager implements - ConditionalElementListener, BreakOpportunity { +public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** * logging instance @@ -79,13 +80,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl private MinOptMax foBlockSpaceBefore; private MinOptMax foBlockSpaceAfter; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private int horizontalOverflow; private double contentRectOffsetX = 0; private double contentRectOffsetY = 0; @@ -96,6 +90,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl */ public BlockContainerLayoutManager(BlockContainer node) { super(node); + setGeneratesBlockArea(true); } /** {@inheritDoc} */ @@ -128,6 +123,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl .spaceAfter.getSpace().getOptimum(this).getLength().getValue(this); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getBlockContainerFO().getCommonBorderPaddingBackground(); + } + private void resetSpaces() { this.discardBorderBefore = false; this.discardBorderAfter = false; @@ -995,51 +995,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl } /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ public boolean handleOverflow(int milliPoints) { if (milliPoints > this.horizontalOverflow) { this.horizontalOverflow = milliPoints; diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index b29b95cb1..d3bdc7b85 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -32,6 +32,7 @@ import org.apache.fop.area.Block; import org.apache.fop.area.LineArea; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.FONode; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; @@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal; /** * LayoutManager for a block FO. */ -public class BlockLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener, - BreakOpportunity { +public class BlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** logging instance */ private static Log log = LogFactory.getLog(BlockLayoutManager.class); @@ -60,13 +61,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co private int follow = 2000; //private int middleShift = 0; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - /** * Creates a new BlockLayoutManager. * @param inBlock the block FO object to create the layout manager for. @@ -100,6 +94,11 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co .getOptimum(this).getLength().getValue(this); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getBlockFO().getCommonBorderPaddingBackground(); + } + /** {@inheritDoc} */ @Override public List getNextKnuthElements(LayoutContext context, int alignment) { @@ -458,51 +457,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co } /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ @Override public boolean isRestartable() { return true; diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index d11f062cb..250e07727 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -36,6 +36,7 @@ import org.apache.fop.fo.properties.BreakPropertySet; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.SpaceProperty; +import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager; import org.apache.fop.layoutmgr.inline.InlineLayoutManager; import org.apache.fop.traits.MinOptMax; import org.apache.fop.util.ListUtil; @@ -1246,6 +1247,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager public boolean handleOverflow(int milliPoints) { if (getParent() instanceof BlockStackingLayoutManager) { return ((BlockStackingLayoutManager) getParent()).handleOverflow(milliPoints); + } else if (getParent() instanceof InlineContainerLayoutManager) { + return ((InlineContainerLayoutManager) getParent()).handleOverflow(milliPoints); } return false; } diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java index 2a39700e2..75c61b94f 100644 --- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java @@ -58,6 +58,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager */ public FlowLayoutManager(PageSequenceLayoutManager pslm, Flow node) { super(node); + setGeneratesBlockArea(true); setParent(pslm); } diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManager.java b/src/java/org/apache/fop/layoutmgr/LayoutManager.java index 985131bf1..8d1e4001c 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutManager.java @@ -178,6 +178,25 @@ public interface LayoutManager extends PercentBaseContext { List getChangedKnuthElements(List oldList, int alignment); /** + * Whether the FO handled by this layout manager has a descendant (including itself) + * that will generate a line-area. + * + * @return {@code true} if a descendant line-area will be generated, {@code false} otherwise + */ + boolean hasLineAreaDescendant(); + + /** + * Returns the position of the dominant-baseline of this FO's first descendant + * line-area. <p>The behavior of this method is undefined if this FO has no descendant + * line-area, and an exception may be thrown. See {@link #hasLineAreaDescendant()}</p> + * + * @return this FO's space-before plus the distance from the before-edge of its + * allocation-rectangle to the dominant-baseline of the first line-area descendant + * @see #hasLineAreaDescendant() + */ + int getBaselineOffset(); + + /** * Returns the IPD of the content area * @return the IPD of the content area */ diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java b/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java index cf8b74cc0..2ffb48675 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java @@ -75,7 +75,7 @@ import org.apache.fop.layoutmgr.inline.CharacterLayoutManager; import org.apache.fop.layoutmgr.inline.ContentLayoutManager; import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager; import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager; -import org.apache.fop.layoutmgr.inline.ICLayoutManager; +import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager; import org.apache.fop.layoutmgr.inline.InlineLayoutManager; import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM; import org.apache.fop.layoutmgr.inline.LeaderLayoutManager; @@ -261,9 +261,9 @@ public class LayoutManagerMapping implements LayoutManagerMaker { /** a layout manager maker */ public static class InlineLayoutManagerMaker extends Maker { /** {@inheritDoc} */ - public void make(FONode node, List lms) { - lms.add(new InlineLayoutManager((InlineLevel) node)); - } + public void make(FONode node, List lms) { + lms.add(new InlineLayoutManager((InlineLevel) node)); + } } /** a layout manager maker */ @@ -278,9 +278,7 @@ public class LayoutManagerMapping implements LayoutManagerMaker { public static class InlineContainerLayoutManagerMaker extends Maker { /** {@inheritDoc} */ public void make(FONode node, List lms) { - ArrayList childList = new ArrayList(); - super.make(node, childList); - lms.add(new ICLayoutManager((InlineContainer) node, childList)); + lms.add(new InlineContainerLayoutManager((InlineContainer) node)); } } diff --git a/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java new file mode 100644 index 000000000..2ac41e96a --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutmgr; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.traits.MinOptMax; + +/** + * A block-stacking layout manager for an FO that supports spaces, border and padding. + */ +public abstract class SpacedBorderedPaddedBlockLayoutManager extends BlockStackingLayoutManager + implements ConditionalElementListener { + + private static final Log LOG = LogFactory.getLog(BlockLayoutManager.class); + + protected MinOptMax effSpaceBefore; + + protected MinOptMax effSpaceAfter; + + protected boolean discardBorderBefore; + protected boolean discardBorderAfter; + protected boolean discardPaddingBefore; + protected boolean discardPaddingAfter; + + public SpacedBorderedPaddedBlockLayoutManager(FObj node) { + super(node); + } + + public void notifySpace(RelSide side, MinOptMax effectiveLength) { + if (RelSide.BEFORE == side) { + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Space " + side + ", " + + this.effSpaceBefore + "-> " + effectiveLength); + } + this.effSpaceBefore = effectiveLength; + } else { + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Space " + side + ", " + + this.effSpaceAfter + "-> " + effectiveLength); + } + this.effSpaceAfter = effectiveLength; + } + } + + public void notifyBorder(RelSide side, MinOptMax effectiveLength) { + if (effectiveLength == null) { + if (RelSide.BEFORE == side) { + this.discardBorderBefore = true; + } else { + this.discardBorderAfter = true; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Border " + side + " -> " + effectiveLength); + } + } + + public void notifyPadding(RelSide side, MinOptMax effectiveLength) { + if (effectiveLength == null) { + if (RelSide.BEFORE == side) { + this.discardPaddingBefore = true; + } else { + this.discardPaddingAfter = true; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Padding " + side + " -> " + effectiveLength); + } + } + + @Override + public int getBaselineOffset() { + int baselineOffset = super.getBaselineOffset(); + if (effSpaceBefore != null) { + baselineOffset += effSpaceBefore.getOpt(); + } + if (!discardBorderBefore) { + baselineOffset += getCommonBorderPaddingBackground().getBorderBeforeWidth(false); + } + if (!discardPaddingBefore) { + baselineOffset += getCommonBorderPaddingBackground().getPaddingBefore(false, this); + } + return baselineOffset; + } + + /** + * Returns the {@link CommonBorderPaddingBackground} instance from the FO handled by this layout manager. + */ + protected abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground(); + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java b/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java index c1992965c..192956abc 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java +++ b/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java @@ -295,7 +295,7 @@ public class AlignmentContext implements Constants { * Return the dominant baseline identifier. * @return the dominant baseline identifier */ - private int getDominantBaselineIdentifier() { + public int getDominantBaselineIdentifier() { return actualBaselineTable.getDominantBaselineIdentifier(); } diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java index b3c768987..c067b040f 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java @@ -332,6 +332,15 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager return parentLM.getPSLM(); } + + public boolean hasLineAreaDescendant() { + return true; + } + + public int getBaselineOffset() { + return childLM.getBaselineOffset(); + } + // --------- Property Resolution related functions --------- // /** diff --git a/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java deleted file mode 100644 index 7fe90f63c..000000000 --- a/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.layoutmgr.inline; - -// Java -import java.util.List; - -// FOP -import org.apache.fop.area.inline.InlineArea; -import org.apache.fop.fo.flow.InlineContainer; -/** - * This creates a single inline container area after - * laying out the child block areas. All footnotes, floats - * and id areas are maintained for later retrieval. - */ -public class ICLayoutManager extends LeafNodeLayoutManager { - private List childrenLM; - - /** - * Construct inline container layout manager. - * @param node inline container FO node - * @param childLM child layout manager - */ - public ICLayoutManager(InlineContainer node, List childLM) { - super(node); - childrenLM = childLM; - } - - /** - * @param index an integer - * @return an inline area or null - */ - public InlineArea get(int index) { - return null; - } - -} diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java new file mode 100644 index 000000000..54237a914 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java @@ -0,0 +1,326 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutmgr.inline; + +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.apache.fop.area.Area; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.Container; +import org.apache.fop.area.inline.InlineViewport; +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.LengthBase; +import org.apache.fop.datatypes.SimplePercentBaseContext; +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.flow.InlineContainer; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.LengthRangeProperty; +import org.apache.fop.fo.properties.Property; +import org.apache.fop.layoutmgr.AbstractLayoutManager; +import org.apache.fop.layoutmgr.AreaAdditionUtil; +import org.apache.fop.layoutmgr.BlockLevelEventProducer; +import org.apache.fop.layoutmgr.ElementListUtils; +import org.apache.fop.layoutmgr.InlineKnuthSequence; +import org.apache.fop.layoutmgr.KnuthPossPosIter; +import org.apache.fop.layoutmgr.KnuthSequence; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.ListElement; +import org.apache.fop.layoutmgr.NonLeafPosition; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.SpaceResolver; +import org.apache.fop.layoutmgr.TraitSetter; + +/** + * This creates a single inline container area after + * laying out the child block areas. All footnotes, floats + * and id areas are maintained for later retrieval. + */ +public class InlineContainerLayoutManager extends AbstractLayoutManager implements InlineLevelLayoutManager { + + private CommonBorderPaddingBackground borderProps; + private int contentAreaIPD; + private int contentAreaBPD; + + private List<ListElement> childElements; + private int ipdOverflow; + private AlignmentContext alignmentContext; + private InlineViewport currentViewport; + private Container referenceArea; + + public InlineContainerLayoutManager(InlineContainer node) { + super(node); + setGeneratesReferenceArea(true); + } + + @Override + public void initialize() { + InlineContainer node = (InlineContainer) fobj; + borderProps = node.getCommonBorderPaddingBackground(); + } + + private InlineContainer getInlineContainer() { + assert fobj instanceof InlineContainer; + return (InlineContainer) fobj; + } + + @Override + public List<KnuthSequence> getNextKnuthElements(LayoutContext context, int alignment) { + determineIPD(context); + childElements = getChildKnuthElements(context, alignment); + determineBPD(); + alignmentContext = makeAlignmentContext(context); + Position position = new Position(this, 0); + KnuthSequence knuthSequence = new InlineKnuthSequence(); + knuthSequence.add(new KnuthInlineBox(contentAreaIPD, alignmentContext, position, false)); + List<KnuthSequence> knuthElements = new ArrayList<KnuthSequence>(1); + knuthElements.add(knuthSequence); + setFinished(true); + return knuthElements; + } + + private void determineIPD(LayoutContext layoutContext) { + LengthRangeProperty ipd = getInlineContainer().getInlineProgressionDimension(); + Property optimum = ipd.getOptimum(this); + if (optimum.isAuto()) { + contentAreaIPD = layoutContext.getRefIPD(); + InlineLevelEventProducer eventProducer = InlineLevelEventProducer.Provider.get( + fobj.getUserAgent().getEventBroadcaster()); + eventProducer.inlineContainerAutoIPDNotSupported(this, contentAreaIPD / 1000f); + } else { + contentAreaIPD = optimum.getLength().getValue(this); + } + } + + private List<ListElement> getChildKnuthElements(LayoutContext layoutContext, int alignment) { + List<ListElement> allChildElements = new LinkedList<ListElement>(); + LayoutManager childLM; + while ((childLM = getChildLM()) != null) { + LayoutContext childLC = LayoutContext.offspringOf(layoutContext); + childLC.setRefIPD(contentAreaIPD); + @SuppressWarnings("unchecked") + List<ListElement> childElements = childLM.getNextKnuthElements(childLC, alignment); + allChildElements.addAll(childElements); + } + handleIPDOverflow(); + wrapPositions(allChildElements); + SpaceResolver.resolveElementList(allChildElements); + SpaceResolver.performConditionalsNotification(allChildElements, 0, allChildElements.size() - 1, -1); + return allChildElements; + } + + private void determineBPD() { + LengthRangeProperty bpd = getInlineContainer().getBlockProgressionDimension(); + Property optimum = bpd.getOptimum(this); + int actualBPD = ElementListUtils.calcContentLength(childElements); + if (optimum.isAuto()) { + contentAreaBPD = actualBPD; + } else { + double bpdValue = optimum.getLength().getNumericValue(this); + if (bpdValue < 0) { + contentAreaBPD = actualBPD; + } else { + contentAreaBPD = (int) Math.round(bpdValue); + if (contentAreaBPD < actualBPD) { + BlockLevelEventProducer eventProducer = getBlockLevelEventProducer(); + eventProducer.viewportBPDOverflow(this, fobj.getName(), + actualBPD - contentAreaBPD, needClip(), canRecoverFromOverflow(), + fobj.getLocator()); + } + } + } + } + + protected AlignmentContext makeAlignmentContext(LayoutContext context) { + InlineContainer ic = (InlineContainer) fobj; + AlignmentContext ac = new AlignmentContext(contentAreaBPD, + ic.getAlignmentAdjust(), ic.getAlignmentBaseline(), + ic.getBaselineShift(), ic.getDominantBaseline(), + context.getAlignmentContext()); + int baselineOffset = getAlignmentPoint(ac.getDominantBaselineIdentifier()); + ac.resizeLine(contentAreaBPD, baselineOffset); + return ac; + } + + private void handleIPDOverflow() { + if (ipdOverflow > 0) { + BlockLevelEventProducer eventProducer = getBlockLevelEventProducer(); + eventProducer.viewportIPDOverflow(this, fobj.getName(), + ipdOverflow, needClip(), canRecoverFromOverflow(), + fobj.getLocator()); + } + } + + private void wrapPositions(List<ListElement> elements) { + for (ListElement element : elements) { + Position position = new NonLeafPosition(this, element.getPosition()); + notifyPos(position); + element.setPosition(position); + } + } + + private BlockLevelEventProducer getBlockLevelEventProducer() { + return BlockLevelEventProducer.Provider.get(fobj.getUserAgent().getEventBroadcaster()); + } + + private boolean canRecoverFromOverflow() { + return getInlineContainer().getOverflow() != EN_ERROR_IF_OVERFLOW; + } + + private int getAlignmentPoint(int dominantBaseline) { + Length alignmentAdjust = getInlineContainer().getAlignmentAdjust(); + int baseline = alignmentAdjust.getEnum(); + if (baseline == Constants.EN_AUTO) { + return getInlineContainerBaselineOffset(getInlineContainer().getAlignmentBaseline()); + } else if (baseline == Constants.EN_BASELINE) { + return getInlineContainerBaselineOffset(dominantBaseline); + } else if (baseline != 0) { + return getInlineContainerBaselineOffset(baseline); + } else { + int baselineOffset = getInlineContainerBaselineOffset(dominantBaseline); + int lineHeight = getInlineContainer().getLineHeight().getOptimum(this).getLength().getValue(this); + int adjust = alignmentAdjust.getValue( + new SimplePercentBaseContext(null, LengthBase.ALIGNMENT_ADJUST, lineHeight)); + return baselineOffset + adjust; + } + } + + private int getInlineContainerBaselineOffset(int property) { + switch (property) { + case Constants.EN_BEFORE_EDGE: + case Constants.EN_TEXT_BEFORE_EDGE: + return 0; + case Constants.EN_AFTER_EDGE: + case Constants.EN_TEXT_AFTER_EDGE: + return contentAreaBPD; + case Constants.EN_MIDDLE: + case Constants.EN_CENTRAL: + case Constants.EN_MATHEMATICAL: + return contentAreaBPD / 2; + case Constants.EN_IDEOGRAPHIC: + return contentAreaBPD * 7 / 10; + case Constants.EN_ALPHABETIC: + return contentAreaBPD * 6 / 10; + case Constants.EN_HANGING: + return contentAreaBPD * 2 / 10; + case Constants.EN_AUTO: + case Constants.EN_BASELINE: + return hasLineAreaDescendant() ? getBaselineOffset() : contentAreaBPD; + default: + throw new AssertionError("Unknown baseline value: " + property); + } + } + + @Override + public void addAreas(PositionIterator posIter, LayoutContext context) { + Position inlineContainerPosition = null; + while (posIter.hasNext()) { + /* + * Should iterate only once, but hasNext must be called twice for its + * side-effects to apply and the iterator to switch to the next LM. + */ + assert inlineContainerPosition == null; + inlineContainerPosition = posIter.next(); + assert inlineContainerPosition.getLM() == this; + } + assert inlineContainerPosition != null; + KnuthPossPosIter childPosIter = new KnuthPossPosIter(childElements); + AreaAdditionUtil.addAreas(this, childPosIter, context); + } + + @Override + public Area getParentArea(Area childArea) { + if (referenceArea == null) { + referenceArea = new Container(); + referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); + TraitSetter.setProducerID(referenceArea, fobj.getId()); + referenceArea.setIPD(contentAreaIPD); + currentViewport = new InlineViewport(referenceArea); + currentViewport.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); + TraitSetter.setProducerID(currentViewport, fobj.getId()); + currentViewport.setBlockProgressionOffset(alignmentContext.getOffset()); + currentViewport.setIPD(getContentAreaIPD()); + currentViewport.setBPD(getContentAreaBPD()); + TraitSetter.addBackground(currentViewport, borderProps, this); + currentViewport.setClip(needClip()); + currentViewport.setContentPosition( + new Rectangle2D.Float(0, 0, getContentAreaIPD(), getContentAreaBPD())); + getParent().addChildArea(currentViewport); + } + return referenceArea; + } + + @Override + public int getContentAreaIPD() { + return contentAreaIPD; + } + + @Override + public int getContentAreaBPD() { + return contentAreaBPD; + } + + @Override + public void addChildArea(Area childArea) { + referenceArea.addChildArea(childArea); + } + + private boolean needClip() { + int overflow = getInlineContainer().getOverflow(); + return (overflow == EN_HIDDEN || overflow == EN_ERROR_IF_OVERFLOW); + } + + public boolean handleOverflow(int milliPoints) { + ipdOverflow = Math.max(ipdOverflow, milliPoints); + return true; + } + + public List addALetterSpaceTo(List oldList) { + return oldList; + } + + public List addALetterSpaceTo(List oldList, int depth) { + return oldList; + } + + public String getWordChars(Position pos) { + return ""; + } + + public void hyphenate(Position pos, HyphContext hyphContext) { + } + + public boolean applyChanges(List oldList) { + return false; + } + + public boolean applyChanges(List oldList, int depth) { + return false; + } + + public List getChangedKnuthElements(List oldList, int alignment, int depth) { + return oldList; + } + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java index 15284ae0a..332e14935 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java @@ -67,4 +67,13 @@ public interface InlineLevelEventProducer extends EventProducer { */ void lineOverflows(Object source, String elementName, int line, int overflowLength, Locator loc); + /** + * Auto IPD on inline-container is not supported. + * + * @param source the event source + * @param fallback the value in points that will be used as a fallback + * @event.severity WARN + */ + void inlineContainerAutoIPDNotSupported(Object source, float fallback); + } diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml index 66d352eb7..8d699f6bc 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml @@ -20,4 +20,5 @@ <message key="locator">[ (See position {loc})| (See {#gatherContextInfo})| (No context info available)]</message> <message key="leaderWithoutContent">fo:leader is set to "use-content" but has no content.{{locator}}</message> <message key="lineOverflows">The contents of {elementName} line {line} exceed the available area in the inline-progression direction by {overflowLength,choice,50000#{overflowLength} millipoints|50000<more than 50 points}.{{locator}}</message> + <message key="inlineContainerAutoIPDNotSupported">A value of "auto" for the inline-progression-dimension property on fo:inline-container is not supported. Falling back to {fallback}pt.{{locator}}</message> </catalogue> diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index b3987a075..25d8c0872 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -160,6 +160,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager private final int follow; private AlignmentContext alignmentContext; + private int baselineOffset = -1; + private List<KnuthSequence> knuthParagraphs; private LineLayoutPossibilities lineLayouts; @@ -556,7 +558,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager private int constantLineHeight = 12000; - /** * Create a new Line Layout Manager. * This is used by the block layout manager to create @@ -939,7 +940,11 @@ public class LineLayoutManager extends InlineStackingLayoutManager while (listIter.hasNext()) { ListElement tempElement; tempElement = (ListElement) listIter.next(); - if (tempElement.getLayoutManager() != this) { + LayoutManager lm = tempElement.getLayoutManager(); + if (baselineOffset < 0 && lm != null && lm.hasLineAreaDescendant()) { + baselineOffset = lm.getBaselineOffset(); + } + if (lm != this) { tempElement.setPosition(notifyPos(new NonLeafPosition(this, tempElement.getPosition()))); } @@ -987,6 +992,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager } startIndex = endIndex + 1; LineBreakPosition lbp = (LineBreakPosition) llPoss.getChosenPosition(i); + if (baselineOffset < 0) { + baselineOffset = lbp.spaceBefore + lbp.baseline; + } returnList.add(new KnuthBlockBox( lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter, footnoteList, lbp, false)); @@ -1424,6 +1432,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager } } + @Override + public boolean hasLineAreaDescendant() { + return true; + } + + @Override + public int getBaselineOffset() { + return baselineOffset; + } + /** * Add the areas with the break points. * diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java index 53f51cd32..625b43ee5 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java @@ -30,12 +30,11 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.area.Trait; import org.apache.fop.area.inline.TextArea; -import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; -import org.apache.fop.complexscripts.util.CharScript; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FOText; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontSelector; +import org.apache.fop.fonts.GlyphMapping; import org.apache.fop.layoutmgr.InlineKnuthSequence; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; @@ -65,91 +64,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager { private static final int SOFT_HYPHEN_PENALTY = 1; /** - * Store information about each potential text area. - * Index of character which ends the area, IPD of area, including - * any word-space and letter-space. - * Number of word-spaces? - */ - private class AreaInfo { - - private final int startIndex; - private final int breakIndex; - private int wordCharLength; - private final int wordSpaceCount; - private int letterSpaceCount; - private MinOptMax areaIPD; - private final boolean isHyphenated; - private final boolean isSpace; - private boolean breakOppAfter; - private final Font font; - private final int level; - private final int[][] gposAdjustments; - - AreaInfo( - int startIndex, int breakIndex, int wordSpaceCount, int letterSpaceCount, - MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter, - Font font, int level, int[][] gposAdjustments) { - assert startIndex <= breakIndex; - this.startIndex = startIndex; - this.breakIndex = breakIndex; - this.wordCharLength = -1; - this.wordSpaceCount = wordSpaceCount; - this.letterSpaceCount = letterSpaceCount; - this.areaIPD = areaIPD; - this.isHyphenated = isHyphenated; - this.isSpace = isSpace; - this.breakOppAfter = breakOppAfter; - this.font = font; - this.level = level; - this.gposAdjustments = gposAdjustments; - } - - /** - * Obtain number of 'characters' contained in word. If word - * is mapped, then this number may be less than or greater than the - * original length (breakIndex - startIndex). We compute and - * memoize thius length upon first invocation of this method. - */ - private int getWordLength() { - if (wordCharLength == -1) { - if (foText.hasMapping(startIndex, breakIndex)) { - wordCharLength = foText.getMapping(startIndex, breakIndex).length(); - } else { - assert breakIndex >= startIndex; - wordCharLength = breakIndex - startIndex; - } - } - return wordCharLength; - } - - private void addToAreaIPD(MinOptMax idp) { - areaIPD = areaIPD.plus(idp); - } - - public String toString() { - return super.toString() + "{" - + "interval = [" + startIndex + "," + breakIndex + "]" - + ", isSpace = " + isSpace - + ", level = " + level - + ", areaIPD = " + areaIPD - + ", letterSpaceCount = " + letterSpaceCount - + ", wordSpaceCount = " + wordSpaceCount - + ", isHyphenated = " + isHyphenated - + ", font = " + font - + "}"; - } - } - - /** * this class stores information about changes in vecAreaInfo which are not yet applied */ private final class PendingChange { - private final AreaInfo areaInfo; + private final GlyphMapping mapping; private final int index; - private PendingChange(final AreaInfo areaInfo, final int index) { - this.areaInfo = areaInfo; + private PendingChange(final GlyphMapping mapping, final int index) { + this.mapping = mapping; this.index = index; } } @@ -160,7 +83,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { private static final Log LOG = LogFactory.getLog(TextLayoutManager.class); // Hold all possible breaks for the text in this LM's FO. - private final List areaInfos; + private final List<GlyphMapping> mappings; /** Non-space characters on which we can end a line. */ private static final String BREAK_CHARS = "-/"; @@ -216,7 +139,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { public TextLayoutManager(FOText node) { foText = node; letterSpaceAdjustArray = new MinOptMax[node.length() + 1]; - areaInfos = new ArrayList(); + mappings = new ArrayList<GlyphMapping>(); } private KnuthPenalty makeZeroWidthPenalty(int penaltyValue) { @@ -274,61 +197,61 @@ public class TextLayoutManager extends LeafNodeLayoutManager { public void addAreas(final PositionIterator posIter, final LayoutContext context) { // Add word areas - AreaInfo areaInfo; + GlyphMapping mapping; int wordSpaceCount = 0; int letterSpaceCount = 0; - int firstAreaInfoIndex = -1; - int lastAreaInfoIndex = 0; + int firstMappingIndex = -1; + int lastMappingIndex = 0; MinOptMax realWidth = MinOptMax.ZERO; /* On first area created, add any leading space. * Calculate word-space stretch value. */ - AreaInfo lastAreaInfo = null; + GlyphMapping lastMapping = null; while (posIter.hasNext()) { final LeafPosition tbpNext = (LeafPosition) posIter.next(); if (tbpNext == null) { continue; //Ignore elements without Positions } if (tbpNext.getLeafPos() != -1) { - areaInfo = (AreaInfo) areaInfos.get(tbpNext.getLeafPos()); - if (lastAreaInfo == null - || (areaInfo.font != lastAreaInfo.font) - || (areaInfo.level != lastAreaInfo.level)) { - if (lastAreaInfo != null) { - addAreaInfoAreas(lastAreaInfo, wordSpaceCount, - letterSpaceCount, firstAreaInfoIndex, - lastAreaInfoIndex, realWidth, context); + mapping = mappings.get(tbpNext.getLeafPos()); + if (lastMapping == null + || (mapping.font != lastMapping.font) + || (mapping.level != lastMapping.level)) { + if (lastMapping != null) { + addMappingAreas(lastMapping, wordSpaceCount, + letterSpaceCount, firstMappingIndex, + lastMappingIndex, realWidth, context); } - firstAreaInfoIndex = tbpNext.getLeafPos(); + firstMappingIndex = tbpNext.getLeafPos(); wordSpaceCount = 0; letterSpaceCount = 0; realWidth = MinOptMax.ZERO; } - wordSpaceCount += areaInfo.wordSpaceCount; - letterSpaceCount += areaInfo.letterSpaceCount; - realWidth = realWidth.plus(areaInfo.areaIPD); - lastAreaInfoIndex = tbpNext.getLeafPos(); - lastAreaInfo = areaInfo; + wordSpaceCount += mapping.wordSpaceCount; + letterSpaceCount += mapping.letterSpaceCount; + realWidth = realWidth.plus(mapping.areaIPD); + lastMappingIndex = tbpNext.getLeafPos(); + lastMapping = mapping; } } - if (lastAreaInfo != null) { - addAreaInfoAreas(lastAreaInfo, wordSpaceCount, letterSpaceCount, firstAreaInfoIndex, - lastAreaInfoIndex, realWidth, context); + if (lastMapping != null) { + addMappingAreas(lastMapping, wordSpaceCount, letterSpaceCount, firstMappingIndex, + lastMappingIndex, realWidth, context); } } - private void addAreaInfoAreas(AreaInfo areaInfo, int wordSpaceCount, int letterSpaceCount, - int firstAreaInfoIndex, int lastAreaInfoIndex, + private void addMappingAreas(GlyphMapping mapping, int wordSpaceCount, int letterSpaceCount, + int firstMappingIndex, int lastMappingIndex, MinOptMax realWidth, LayoutContext context) { // TODO: These two statements (if, for) were like this before my recent - // changes. However, it seems as if they should use the AreaInfo from - // firstAreaInfoIndex.. lastAreaInfoIndex rather than just the last areaInfo. + // changes. However, it seems as if they should use the GlyphMapping from + // firstMappingIndex.. lastMappingIndex rather than just the last mapping. // This needs to be checked. - int textLength = areaInfo.getWordLength(); - if (areaInfo.letterSpaceCount == textLength && !areaInfo.isHyphenated + int textLength = mapping.getWordLength(); + if (mapping.letterSpaceCount == textLength && !mapping.isHyphenated && context.isLastArea()) { // the line ends at a character like "/" or "-"; // remove the letter space after the last character @@ -336,7 +259,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { letterSpaceCount--; } - for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) { + for (int i = mapping.startIndex; i < mapping.endIndex; i++) { MinOptMax letterSpaceAdjustment = letterSpaceAdjustArray[i + 1]; if (letterSpaceAdjustment != null && letterSpaceAdjustment.isElastic()) { letterSpaceCount++; @@ -344,7 +267,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } // add hyphenation character if the last word is hyphenated - if (context.isLastArea() && areaInfo.isHyphenated) { + if (context.isLastArea() && mapping.isHyphenated) { realWidth = realWidth.plus(hyphIPD); } @@ -385,8 +308,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { totalAdjust = difference; } - TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstAreaInfoIndex, - lastAreaInfoIndex, context.isLastArea(), areaInfo.font).build(); + TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstMappingIndex, + lastMappingIndex, context.isLastArea(), mapping.font).build(); // wordSpaceDim is computed in relation to wordSpaceIPD.opt // but the renderer needs to know the adjustment in relation @@ -417,15 +340,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager { private final MinOptMax width; // content ipd private final int adjust; // content ipd adjustment private final LayoutContext context; // layout context - private final int firstIndex; // index of first AreaInfo - private final int lastIndex; // index of last AreaInfo + private final int firstIndex; // index of first GlyphMapping + private final int lastIndex; // index of last GlyphMapping private final boolean isLastArea; // true if last inline area in line area private final Font font; // applicable font // other, non-constructor state private TextArea textArea; // text area being constructed private int blockProgressionDimension; // calculated bpd - private AreaInfo areaInfo; // current area info when iterating over words + private GlyphMapping mapping; // current mapping when iterating over words private StringBuffer wordChars; // current word's character buffer private int[] letterSpaceAdjust; // current word's letter space adjustments private int letterSpaceAdjustIndex; // last written letter space adjustment index @@ -442,8 +365,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { * @param width the MinOptMax width of the content * @param adjust the total ipd adjustment with respect to the optimal width * @param context the layout context - * @param firstIndex the index of the first AreaInfo used for the TextArea - * @param lastIndex the index of the last AreaInfo used for the TextArea + * @param firstIndex the index of the first GlyphMapping used for the TextArea + * @param lastIndex the index of the last GlyphMapping used for the TextArea * @param isLastArea is this TextArea the last in a line? * @param font Font to be used in this particular TextArea */ @@ -516,30 +439,30 @@ public class TextLayoutManager extends LeafNodeLayoutManager { * Sets the text of the TextArea, split into words and spaces. */ private void setText() { - int areaInfoIndex = -1; + int mappingIndex = -1; int wordCharLength = 0; for (int wordIndex = firstIndex; wordIndex <= lastIndex; wordIndex++) { - areaInfo = getAreaInfo(wordIndex); - if (areaInfo.isSpace) { + mapping = getGlyphMapping(wordIndex); + if (mapping.isSpace) { addSpaces(); } else { - // areaInfo stores information about a word fragment - if (areaInfoIndex == -1) { + // mapping stores information about a word fragment + if (mappingIndex == -1) { // here starts a new word - areaInfoIndex = wordIndex; + mappingIndex = wordIndex; wordCharLength = 0; } - wordCharLength += areaInfo.getWordLength(); + wordCharLength += mapping.getWordLength(); if (isWordEnd(wordIndex)) { - addWord(areaInfoIndex, wordIndex, wordCharLength); - areaInfoIndex = -1; + addWord(mappingIndex, wordIndex, wordCharLength); + mappingIndex = -1; } } } } - private boolean isWordEnd(int areaInfoIndex) { - return areaInfoIndex == lastIndex || getAreaInfo(areaInfoIndex + 1).isSpace; + private boolean isWordEnd(int mappingIndex) { + return mappingIndex == lastIndex || getGlyphMapping(mappingIndex + 1).isSpace; } /** @@ -564,10 +487,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // iterate over word's fragments, adding word chars (with bidi // levels), letter space adjustments, and glyph position adjustments for (int i = startIndex; i <= endIndex; i++) { - AreaInfo wordAreaInfo = getAreaInfo(i); - addWordChars(wordAreaInfo); - addLetterAdjust(wordAreaInfo); - if (addGlyphPositionAdjustments(wordAreaInfo)) { + GlyphMapping wordMapping = getGlyphMapping(i); + addWordChars(wordMapping); + addLetterAdjust(wordMapping); + if (addGlyphPositionAdjustments(wordMapping)) { gposAdjusted = true; } } @@ -617,7 +540,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } private boolean isHyphenated(int endIndex) { - return isLastArea && endIndex == lastIndex && areaInfo.isHyphenated; + return isLastArea && endIndex == lastIndex && mapping.isHyphenated; } private void addHyphenationChar() { @@ -632,21 +555,54 @@ public class TextLayoutManager extends LeafNodeLayoutManager { * (1) concatenate (possibly mapped) word characters to word character buffer; * (2) concatenante (possibly mapped) word bidi levels to levels buffer; * (3) update word's IPD with optimal IPD of fragment. - * @param wordAreaInfo fragment info + * @param wordMapping fragment info */ - private void addWordChars(AreaInfo wordAreaInfo) { - int s = wordAreaInfo.startIndex; - int e = wordAreaInfo.breakIndex; - if (foText.hasMapping(s, e)) { - wordChars.append(foText.getMapping(s, e)); - addWordLevels(foText.getMappingBidiLevels(s, e)); + private void addWordChars(GlyphMapping wordMapping) { + int s = wordMapping.startIndex; + int e = wordMapping.endIndex; + if (wordMapping.mapping != null) { + wordChars.append(wordMapping.mapping); + addWordLevels(getMappingBidiLevels(wordMapping)); } else { for (int i = s; i < e; i++) { wordChars.append(foText.charAt(i)); } addWordLevels(foText.getBidiLevels(s, e)); } - wordIPD += wordAreaInfo.areaIPD.getOpt(); + wordIPD += wordMapping.areaIPD.getOpt(); + } + + /** + * Obtain bidirectional levels of mapping of characters over specific interval. + * @param start index in character buffer + * @param end index in character buffer + * @return a (possibly empty) array of bidi levels or null + * in case no bidi levels have been assigned + */ + private int[] getMappingBidiLevels(GlyphMapping mapping) { + if (mapping.mapping != null) { + int nc = mapping.endIndex - mapping.startIndex; + int nm = mapping.mapping.length(); + int[] la = foText.getBidiLevels(mapping.startIndex, mapping.endIndex); + if (la == null) { + return null; + } else if (nm == nc) { // mapping is same length as mapped range + return la; + } else if (nm > nc) { // mapping is longer than mapped range + int[] ma = new int[nm]; + System.arraycopy(la, 0, ma, 0, la.length); + for (int i = la.length, n = ma.length, l = (i > 0) ? la[i - 1] : 0; i < n; i++) { + ma[i] = l; + } + return ma; + } else { // mapping is shorter than mapped range + int[] ma = new int[nm]; + System.arraycopy(la, 0, ma, 0, ma.length); + return ma; + } + } else { + return foText.getBidiLevels(mapping.startIndex, mapping.endIndex); + } } /** @@ -672,16 +628,16 @@ public class TextLayoutManager extends LeafNodeLayoutManager { /** * Given a word area info associated with a word fragment, * concatenate letter space adjustments for each (possibly mapped) character. - * @param wordAreaInfo fragment info + * @param wordMapping fragment info */ - private void addLetterAdjust(AreaInfo wordAreaInfo) { - int letterSpaceCount = wordAreaInfo.letterSpaceCount; - int wordLength = wordAreaInfo.getWordLength(); + private void addLetterAdjust(GlyphMapping wordMapping) { + int letterSpaceCount = wordMapping.letterSpaceCount; + int wordLength = wordMapping.getWordLength(); int taAdjust = textArea.getTextLetterSpaceAdjust(); for (int i = 0, n = wordLength; i < n; i++) { int j = letterSpaceAdjustIndex + i; if (j > 0) { - int k = wordAreaInfo.startIndex + i; + int k = wordMapping.startIndex + i; MinOptMax adj = (k < letterSpaceAdjustArray.length) ? letterSpaceAdjustArray [ k ] : null; letterSpaceAdjust [ j ] = (adj == null) ? 0 : adj.getOpt(); @@ -697,14 +653,14 @@ public class TextLayoutManager extends LeafNodeLayoutManager { /** * Given a word area info associated with a word fragment, * concatenate glyph position adjustments for each (possibly mapped) character. - * @param wordAreaInfo fragment info + * @param wordMapping fragment info * @return true if an adjustment was non-zero */ - private boolean addGlyphPositionAdjustments(AreaInfo wordAreaInfo) { + private boolean addGlyphPositionAdjustments(GlyphMapping wordMapping) { boolean adjusted = false; - int[][] gpa = wordAreaInfo.gposAdjustments; + int[][] gpa = wordMapping.gposAdjustments; int numAdjusts = (gpa != null) ? gpa.length : 0; - int wordLength = wordAreaInfo.getWordLength(); + int wordLength = wordMapping.getWordLength(); if (numAdjusts > 0) { int need = gposAdjustmentsIndex + numAdjusts; if (need <= gposAdjustments.length) { @@ -733,7 +689,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } /** - * The <code>AreaInfo</code> stores information about spaces. + * The <code>GlyphMapping</code> stores information about spaces. * <p/> * Add the spaces - except zero-width spaces - to the TextArea. */ @@ -743,16 +699,16 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // divide the area info's allocated IPD evenly among the // non-zero-width space characters int numZeroWidthSpaces = 0; - for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) { + for (int i = mapping.startIndex; i < mapping.endIndex; i++) { char spaceChar = foText.charAt(i); if (CharUtilities.isZeroWidthSpace(spaceChar)) { numZeroWidthSpaces++; } } - int numSpaces = areaInfo.breakIndex - areaInfo.startIndex - numZeroWidthSpaces; - int spaceIPD = areaInfo.areaIPD.getOpt() / ((numSpaces > 0) ? numSpaces : 1); + int numSpaces = mapping.endIndex - mapping.startIndex - numZeroWidthSpaces; + int spaceIPD = mapping.areaIPD.getOpt() / ((numSpaces > 0) ? numSpaces : 1); // add space area children, one for each non-zero-width space character - for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) { + for (int i = mapping.startIndex; i < mapping.endIndex; i++) { char spaceChar = foText.charAt(i); int level = foText.bidiLevelAt(i); if (!CharUtilities.isZeroWidthSpace(spaceChar)) { @@ -766,39 +722,20 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } - private void addAreaInfo(AreaInfo ai) { - addAreaInfo(areaInfos.size(), ai); + private void addGlyphMapping(GlyphMapping mapping) { + addGlyphMapping(mappings.size(), mapping); } - private void addAreaInfo(int index, AreaInfo ai) { - areaInfos.add(index, ai); + private void addGlyphMapping(int index, GlyphMapping mapping) { + mappings.add(index, mapping); } - private void removeAreaInfo(int index) { - areaInfos.remove(index); + private void removeGlyphMapping(int index) { + mappings.remove(index); } - private AreaInfo getAreaInfo(int index) { - return (AreaInfo) areaInfos.get(index); - } - - private void addToLetterAdjust(int index, int width) { - if (letterSpaceAdjustArray[index] == null) { - letterSpaceAdjustArray[index] = MinOptMax.getInstance(width); - } else { - letterSpaceAdjustArray[index] = letterSpaceAdjustArray[index].plus(width); - } - } - - /** - * Indicates whether a character is a space in terms of this layout manager. - * @param ch the character - * @return true if it's a space - */ - private static boolean isSpace(final char ch) { - return ch == CharUtilities.SPACE - || CharUtilities.isNonBreakableSpace(ch) - || CharUtilities.isFixedWidthSpace(ch); + private GlyphMapping getGlyphMapping(int index) { + return mappings.get(index); } /** {@inheritDoc} */ @@ -810,8 +747,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { final List returnList = new LinkedList(); KnuthSequence sequence = new InlineKnuthSequence(); - AreaInfo areaInfo = null; - AreaInfo prevAreaInfo = null; + GlyphMapping mapping = null; + GlyphMapping prevMapping = null; returnList.add(sequence); if (LOG.isDebugEnabled()) { @@ -857,24 +794,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } if (inWord) { if (breakOpportunity - || TextLayoutManager.isSpace(ch) + || GlyphMapping.isSpace(ch) || CharUtilities.isExplicitBreak(ch) || ((prevLevel != -1) && (level != prevLevel))) { // this.foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN - prevAreaInfo = processWord(alignment, sequence, prevAreaInfo, ch, + prevMapping = processWord(alignment, sequence, prevMapping, ch, breakOpportunity, true, prevLevel); } } else if (inWhitespace) { if (ch != CharUtilities.SPACE || breakOpportunity) { - prevAreaInfo = processWhitespace(alignment, sequence, + prevMapping = processWhitespace(alignment, sequence, breakOpportunity, prevLevel); } } else { - if (areaInfo != null) { - prevAreaInfo = areaInfo; - processLeftoverAreaInfo(alignment, sequence, areaInfo, + if (mapping != null) { + prevMapping = mapping; + processLeftoverGlyphMapping(alignment, sequence, mapping, ch == CharUtilities.SPACE || breakOpportunity); - areaInfo = null; + mapping = null; } if (breakAction == LineBreakStatus.EXPLICIT_BREAK) { sequence = processLinebreak(returnList, sequence); @@ -888,15 +825,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager { this.foText, this); font.mapChar(ch); // preserved space or non-breaking space: - // create the AreaInfo object - areaInfo = new AreaInfo(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true, + // create the GlyphMapping object + mapping = new GlyphMapping(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true, breakOpportunity, spaceFont, level, null); thisStart = nextStart + 1; } else if (CharUtilities.isFixedWidthSpace(ch) || CharUtilities.isZeroWidthSpace(ch)) { - // create the AreaInfo object + // create the GlyphMapping object Font font = FontSelector.selectFontForCharacterInText(ch, foText, this); MinOptMax ipd = MinOptMax.getInstance(font.getCharWidth(ch)); - areaInfo = new AreaInfo(nextStart, nextStart + 1, 0, 0, ipd, false, true, + mapping = new GlyphMapping(nextStart, nextStart + 1, 0, 0, ipd, false, true, breakOpportunity, font, level, null); thisStart = nextStart + 1; } else if (CharUtilities.isExplicitBreak(ch)) { @@ -904,7 +841,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { thisStart = nextStart + 1; } - inWord = !TextLayoutManager.isSpace(ch) && !CharUtilities.isExplicitBreak(ch); + inWord = !GlyphMapping.isSpace(ch) && !CharUtilities.isExplicitBreak(ch); inWhitespace = ch == CharUtilities.SPACE && foText.getWhitespaceTreatment() != Constants.EN_PRESERVE; prevLevel = level; @@ -913,11 +850,11 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // Process any last elements if (inWord) { - processWord(alignment, sequence, prevAreaInfo, ch, false, false, prevLevel); + processWord(alignment, sequence, prevMapping, ch, false, false, prevLevel); } else if (inWhitespace) { processWhitespace(alignment, sequence, !keepTogether, prevLevel); - } else if (areaInfo != null) { - processLeftoverAreaInfo(alignment, sequence, areaInfo, + } else if (mapping != null) { + processLeftoverGlyphMapping(alignment, sequence, mapping, ch == CharUtilities.ZERO_WIDTH_SPACE); } else if (CharUtilities.isExplicitBreak(ch)) { this.processLinebreak(returnList, sequence); @@ -948,15 +885,14 @@ public class TextLayoutManager extends LeafNodeLayoutManager { return sequence; } - private void processLeftoverAreaInfo(int alignment, - KnuthSequence sequence, AreaInfo areaInfo, - boolean breakOpportunityAfter) { - addAreaInfo(areaInfo); - areaInfo.breakOppAfter = breakOpportunityAfter; - addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1); + private void processLeftoverGlyphMapping(int alignment, KnuthSequence sequence, + GlyphMapping mapping, boolean breakOpportunityAfter) { + addGlyphMapping(mapping); + mapping.breakOppAfter = breakOpportunityAfter; + addElementsForASpace(sequence, alignment, mapping, mappings.size() - 1); } - private AreaInfo processWhitespace(final int alignment, + private GlyphMapping processWhitespace(final int alignment, final KnuthSequence sequence, final boolean breakOpportunity, int level) { if (LOG.isDebugEnabled()) { @@ -964,209 +900,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } // End of whitespace - // create the AreaInfo object + // create the GlyphMapping object assert nextStart >= thisStart; - AreaInfo areaInfo = new AreaInfo( - thisStart, nextStart, nextStart - thisStart, 0, + GlyphMapping mapping = new GlyphMapping( + thisStart, nextStart, nextStart - thisStart, 0, wordSpaceIPD.mult(nextStart - thisStart), false, true, breakOpportunity, spaceFont, level, null); - addAreaInfo(areaInfo); + addGlyphMapping(mapping); // create the elements - addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1); + addElementsForASpace(sequence, alignment, mapping, mappings.size() - 1); thisStart = nextStart; - return areaInfo; - } - - private AreaInfo processWordMapping( - int lastIndex, final Font font, AreaInfo prevAreaInfo, final char breakOpportunityChar, - final boolean endsWithHyphen, int level) { - int s = this.thisStart; // start index of word in FOText character buffer - int e = lastIndex; // end index of word in FOText character buffer - int nLS = 0; // # of letter spaces - String script = foText.getScript(); - String language = foText.getLanguage(); - - if (LOG.isDebugEnabled()) { - LOG.debug("PW: [" + thisStart + "," + lastIndex + "]: {" - + " +M" - + ", level = " + level - + " }"); - } - - // 1. extract unmapped character sequence - CharSequence ics = foText.subSequence(s, e); - - // 2. if script is not specified (by FO property) or it is specified as 'auto', - // then compute dominant script - if ((script == null) || "auto".equals(script)) { - script = CharScript.scriptTagFromCode(CharScript.dominantScript(ics)); - } - if ((language == null) || "none".equals(language)) { - language = "dflt"; - } - - // 3. perform mapping of chars to glyphs ... to glyphs ... to chars - CharSequence mcs = font.performSubstitution(ics, script, language); - - // 4. compute glyph position adjustments on (substituted) characters - int[][] gpa; - if (font.performsPositioning()) { - // handle GPOS adjustments - gpa = font.performPositioning(mcs, script, language); - } else if (font.hasKerning()) { - // handle standard (non-GPOS) kerning adjustments - gpa = getKerningAdjustments(mcs, font); - } else { - gpa = null; - } - - // 5. reorder combining marks so that they precede (within the mapped char sequence) the - // base to which they are applied; N.B. position adjustments (gpa) are reordered in place - mcs = font.reorderCombiningMarks(mcs, gpa, script, language); - - // 6. if mapped sequence differs from input sequence, then memoize mapped sequence - if (!CharUtilities.isSameSequence(mcs, ics)) { - foText.addMapping(s, e, mcs); - } - - // 7. compute word ipd based on final position adjustments - MinOptMax ipd = MinOptMax.ZERO; - for (int i = 0, n = mcs.length(); i < n; i++) { - int c = mcs.charAt(i); - // TODO !BMP - int w = font.getCharWidth(c); - if (w < 0) { - w = 0; - } - if (gpa != null) { - w += gpa [ i ] [ GlyphPositioningTable.Value.IDX_X_ADVANCE ]; - } - ipd = ipd.plus(w); - } - - // [TBD] - handle letter spacing - - return new AreaInfo( - s, e, 0, nLS, ipd, endsWithHyphen, false, - breakOpportunityChar != 0, font, level, gpa); - } - - /** - * Given a mapped character sequence MCS, obtain glyph position adjustments - * from the font's kerning data. - * @param mcs mapped character sequence - * @param font applicable font - * @return glyph position adjustments (or null if no kerning) - */ - private int[][] getKerningAdjustments(CharSequence mcs, final Font font) { - int nc = mcs.length(); - // extract kerning array - int[] ka = new int [ nc ]; // kerning array - for (int i = 0, n = nc, cPrev = -1; i < n; i++) { - int c = mcs.charAt(i); - // TODO !BMP - if (cPrev >= 0) { - ka[i] = font.getKernValue(cPrev, c); - } - cPrev = c; - } - // was there a non-zero kerning? - boolean hasKerning = false; - for (int i = 0, n = nc; i < n; i++) { - if (ka[i] != 0) { - hasKerning = true; - break; - } - } - // if non-zero kerning, then create and return glyph position adjustment array - if (hasKerning) { - int[][] gpa = new int [ nc ] [ 4 ]; - for (int i = 0, n = nc; i < n; i++) { - if (i > 0) { - gpa [ i - 1 ] [ GlyphPositioningTable.Value.IDX_X_ADVANCE ] = ka [ i ]; - } - } - return gpa; - } else { - return null; - } + return mapping; } - private AreaInfo processWordNoMapping(int lastIndex, final Font font, AreaInfo prevAreaInfo, - final char breakOpportunityChar, final boolean endsWithHyphen, int level) { - boolean kerning = font.hasKerning(); - MinOptMax wordIPD = MinOptMax.ZERO; - - if (LOG.isDebugEnabled()) { - LOG.debug("PW: [" + thisStart + "," + lastIndex + "]: {" - + " -M" - + ", level = " + level - + " }"); - } - - for (int i = thisStart; i < lastIndex; i++) { - char currentChar = foText.charAt(i); - - //character width - int charWidth = font.getCharWidth(currentChar); - wordIPD = wordIPD.plus(charWidth); - - //kerning - if (kerning) { - int kern = 0; - if (i > thisStart) { - char previousChar = foText.charAt(i - 1); - kern = font.getKernValue(previousChar, currentChar); - } else if (prevAreaInfo != null - && !prevAreaInfo.isSpace && prevAreaInfo.breakIndex > 0) { - char previousChar = foText.charAt(prevAreaInfo.breakIndex - 1); - kern = font.getKernValue(previousChar, currentChar); - } - if (kern != 0) { - addToLetterAdjust(i, kern); - wordIPD = wordIPD.plus(kern); - } - } - } - if (kerning - && (breakOpportunityChar != 0) - && !TextLayoutManager.isSpace(breakOpportunityChar) - && lastIndex > 0 - && endsWithHyphen) { - int kern = font.getKernValue(foText.charAt(lastIndex - 1), breakOpportunityChar); - if (kern != 0) { - addToLetterAdjust(lastIndex, kern); - //TODO: add kern to wordIPD? - } - } - // shy+chars at start of word: wordLength == 0 && breakOpportunity - // shy only characters in word: wordLength == 0 && !breakOpportunity - int wordLength = lastIndex - thisStart; - int letterSpaces = 0; - if (wordLength != 0) { - letterSpaces = wordLength - 1; - // if there is a break opportunity and the next one (break character) - // is not a space, it could be used as a line end; - // add one more letter space, in case other text follows - if ((breakOpportunityChar != 0) && !TextLayoutManager.isSpace(breakOpportunityChar)) { - letterSpaces++; - } - } - assert letterSpaces >= 0; - wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces)); - - // create and return the AreaInfo object - return new AreaInfo(thisStart, lastIndex, 0, - letterSpaces, wordIPD, - endsWithHyphen, - false, breakOpportunityChar != 0, font, level, null); - } - - private AreaInfo processWord(final int alignment, final KnuthSequence sequence, - AreaInfo prevAreaInfo, final char ch, final boolean breakOpportunity, + private GlyphMapping processWord(final int alignment, final KnuthSequence sequence, + GlyphMapping prevMapping, final char ch, final boolean breakOpportunity, final boolean checkEndsWithHyphen, int level) { //Word boundary found, process widths and kerning @@ -1178,23 +929,20 @@ public class TextLayoutManager extends LeafNodeLayoutManager { && foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN; Font font = FontSelector.selectFontForCharactersInText( foText, thisStart, lastIndex, foText, this); - AreaInfo areaInfo; - if (font.performsSubstitution() || font.performsPositioning()) { - areaInfo = processWordMapping( - lastIndex, font, prevAreaInfo, breakOpportunity ? ch : 0, endsWithHyphen, level); - } else { - areaInfo = processWordNoMapping( - lastIndex, font, prevAreaInfo, breakOpportunity ? ch : 0, endsWithHyphen, level); - } - prevAreaInfo = areaInfo; - addAreaInfo(areaInfo); + char breakOpportunityChar = breakOpportunity ? ch : 0; + char precedingChar = prevMapping != null && !prevMapping.isSpace + && prevMapping.endIndex > 0 ? foText.charAt(prevMapping.endIndex - 1) : 0; + GlyphMapping mapping = GlyphMapping.doGlyphMapping(foText, thisStart, lastIndex, font, + letterSpaceIPD, letterSpaceAdjustArray, precedingChar, breakOpportunityChar, endsWithHyphen, level); + prevMapping = mapping; + addGlyphMapping(mapping); tempStart = nextStart; //add the elements - addElementsForAWordFragment(sequence, alignment, areaInfo, areaInfos.size() - 1); + addElementsForAWordFragment(sequence, alignment, mapping, mappings.size() - 1); thisStart = nextStart; - return prevAreaInfo; + return prevMapping; } /** {@inheritDoc} */ @@ -1214,9 +962,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager { int index = leafPos.getLeafPos(); //element could refer to '-1' position, for non-collapsed spaces (?) if (index > -1) { - AreaInfo areaInfo = getAreaInfo(index); - areaInfo.letterSpaceCount++; - areaInfo.addToAreaIPD(letterSpaceIPD); + GlyphMapping mapping = getGlyphMapping(index); + mapping.letterSpaceCount++; + mapping.addToAreaIPD(letterSpaceIPD); if (TextLayoutManager.BREAK_CHARS.indexOf(foText.charAt(tempStart - 1)) >= 0) { // the last character could be used as a line break // append new elements to oldList @@ -1227,13 +975,13 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } else if (letterSpaceIPD.isStiff()) { // constant letter space: replace the box // give it the unwrapped position of the replaced element - oldListIterator.set(new KnuthInlineBox(areaInfo.areaIPD.getOpt(), + oldListIterator.set(new KnuthInlineBox(mapping.areaIPD.getOpt(), alignmentContext, pos, false)); } else { // adjustable letter space: replace the glue oldListIterator.next(); // this would return the penalty element oldListIterator.next(); // this would return the glue element - oldListIterator.set(new KnuthGlue(letterSpaceIPD.mult(areaInfo.letterSpaceCount), + oldListIterator.set(new KnuthGlue(letterSpaceIPD.mult(mapping.letterSpaceCount), auxiliaryPosition, true)); } } @@ -1242,26 +990,26 @@ public class TextLayoutManager extends LeafNodeLayoutManager { /** {@inheritDoc} */ public void hyphenate(Position pos, HyphContext hyphContext) { - AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos() + changeOffset); - int startIndex = areaInfo.startIndex; + GlyphMapping mapping = getGlyphMapping(((LeafPosition) pos).getLeafPos() + changeOffset); + int startIndex = mapping.startIndex; int stopIndex; boolean nothingChanged = true; - Font font = areaInfo.font; + Font font = mapping.font; - while (startIndex < areaInfo.breakIndex) { + while (startIndex < mapping.endIndex) { MinOptMax newIPD = MinOptMax.ZERO; boolean hyphenFollows; stopIndex = startIndex + hyphContext.getNextHyphPoint(); - if (hyphContext.hasMoreHyphPoints() && stopIndex <= areaInfo.breakIndex) { + if (hyphContext.hasMoreHyphPoints() && stopIndex <= mapping.endIndex) { // stopIndex is the index of the first character // after a hyphenation point hyphenFollows = true; } else { // there are no more hyphenation points, - // or the next one is after areaInfo.breakIndex + // or the next one is after mapping.breakIndex hyphenFollows = false; - stopIndex = areaInfo.breakIndex; + stopIndex = mapping.endIndex; } hyphContext.updateOffset(stopIndex - startIndex); @@ -1286,18 +1034,18 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // add letter spaces boolean isWordEnd - = (stopIndex == areaInfo.breakIndex) - && (areaInfo.letterSpaceCount < areaInfo.getWordLength()); + = (stopIndex == mapping.endIndex) + && (mapping.letterSpaceCount < mapping.getWordLength()); int letterSpaceCount = isWordEnd ? stopIndex - startIndex - 1 : stopIndex - startIndex; assert letterSpaceCount >= 0; newIPD = newIPD.plus(letterSpaceIPD.mult(letterSpaceCount)); - if (!(nothingChanged && stopIndex == areaInfo.breakIndex && !hyphenFollows)) { - // the new AreaInfo object is not equal to the old one + if (!(nothingChanged && stopIndex == mapping.endIndex && !hyphenFollows)) { + // the new GlyphMapping object is not equal to the old one changeList.add( new PendingChange( - new AreaInfo(startIndex, stopIndex, 0, + new GlyphMapping(startIndex, stopIndex, 0, letterSpaceCount, newIPD, hyphenFollows, false, false, font, -1, null), ((LeafPosition) pos).getLeafPos() + changeOffset)); @@ -1324,7 +1072,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { return false; } - // Find the first and last positions in oldList that point to an AreaInfo + // Find the first and last positions in oldList that point to a GlyphMapping // (i.e. getLeafPos() != -1) LeafPosition startPos = null; LeafPosition endPos = null; @@ -1349,8 +1097,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { returnedIndices[0] = (startPos != null ? startPos.getLeafPos() : -1) + changeOffset; returnedIndices[1] = (endPos != null ? endPos.getLeafPos() : -1) + changeOffset; - int areaInfosAdded = 0; - int areaInfosRemoved = 0; + int mappingsAdded = 0; + int mappingsRemoved = 0; if (!changeList.isEmpty()) { int oldIndex = -1; @@ -1360,24 +1108,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager { while (changeListIterator.hasNext()) { currChange = (PendingChange) changeListIterator.next(); if (currChange.index == oldIndex) { - areaInfosAdded++; - changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved; + mappingsAdded++; + changeIndex = currChange.index + mappingsAdded - mappingsRemoved; } else { - areaInfosRemoved++; - areaInfosAdded++; + mappingsRemoved++; + mappingsAdded++; oldIndex = currChange.index; - changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved; - removeAreaInfo(changeIndex); + changeIndex = currChange.index + mappingsAdded - mappingsRemoved; + removeGlyphMapping(changeIndex); } - addAreaInfo(changeIndex, currChange.areaInfo); + addGlyphMapping(changeIndex, currChange.mapping); } changeList.clear(); } // increase the end index for getChangedKnuthElements() - returnedIndices[1] += (areaInfosAdded - areaInfosRemoved); + returnedIndices[1] += (mappingsAdded - mappingsRemoved); // increase offset to use for subsequent paragraphs - changeOffset += (areaInfosAdded - areaInfosRemoved); + changeOffset += (mappingsAdded - mappingsRemoved); return hasChanged; } @@ -1391,16 +1139,16 @@ public class TextLayoutManager extends LeafNodeLayoutManager { final LinkedList returnList = new LinkedList(); for (; returnedIndices[0] <= returnedIndices[1]; returnedIndices[0]++) { - AreaInfo areaInfo = getAreaInfo(returnedIndices[0]); - if (areaInfo.wordSpaceCount == 0) { - // areaInfo refers either to a word or a word fragment - addElementsForAWordFragment(returnList, alignment, areaInfo, returnedIndices[0]); + GlyphMapping mapping = getGlyphMapping(returnedIndices[0]); + if (mapping.wordSpaceCount == 0) { + // mapping refers either to a word or a word fragment + addElementsForAWordFragment(returnList, alignment, mapping, returnedIndices[0]); } else { - // areaInfo refers to a space - addElementsForASpace(returnList, alignment, areaInfo, returnedIndices[0]); + // mapping refers to a space + addElementsForASpace(returnList, alignment, mapping, returnedIndices[0]); } } - setFinished(returnedIndices[0] == areaInfos.size() - 1); + setFinished(returnedIndices[0] == mappings.size() - 1); //ElementListObserver.observe(returnList, "text-changed", null); return returnList; } @@ -1409,9 +1157,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager { public String getWordChars(Position pos) { int leafValue = ((LeafPosition) pos).getLeafPos() + changeOffset; if (leafValue != -1) { - AreaInfo areaInfo = getAreaInfo(leafValue); - StringBuffer buffer = new StringBuffer(areaInfo.getWordLength()); - for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) { + GlyphMapping mapping = getGlyphMapping(leafValue); + StringBuffer buffer = new StringBuffer(mapping.getWordLength()); + for (int i = mapping.startIndex; i < mapping.endIndex; i++) { buffer.append(foText.charAt(i)); } return buffer.toString(); @@ -1420,41 +1168,39 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } } - private void addElementsForASpace(List baseList, int alignment, AreaInfo areaInfo, + private void addElementsForASpace(List baseList, int alignment, GlyphMapping mapping, int leafValue) { LeafPosition mainPosition = new LeafPosition(this, leafValue); - if (!areaInfo.breakOppAfter) { + if (!mapping.breakOppAfter) { // a non-breaking space if (alignment == Constants.EN_JUSTIFY) { // the space can stretch and shrink, and must be preserved // when starting a line baseList.add(makeAuxiliaryZeroWidthBox()); baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE)); - baseList.add(new KnuthGlue(areaInfo.areaIPD, mainPosition, false)); + baseList.add(new KnuthGlue(mapping.areaIPD, mainPosition, false)); } else { // the space does not need to stretch or shrink, and must be // preserved when starting a line - baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt(), null, mainPosition, + baseList.add(new KnuthInlineBox(mapping.areaIPD.getOpt(), null, mainPosition, true)); } } else { - if (foText.charAt(areaInfo.startIndex) != CharUtilities.SPACE + if (foText.charAt(mapping.startIndex) != CharUtilities.SPACE || foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) { // a breaking space that needs to be preserved - baseList - .addAll(getElementsForBreakingSpace(alignment, areaInfo, auxiliaryPosition, 0, - mainPosition, areaInfo.areaIPD.getOpt(), true)); + baseList.addAll(getElementsForBreakingSpace(alignment, mapping, auxiliaryPosition, 0, + mainPosition, mapping.areaIPD.getOpt(), true)); } else { // a (possible block) of breaking spaces - baseList - .addAll(getElementsForBreakingSpace(alignment, areaInfo, mainPosition, - areaInfo.areaIPD.getOpt(), auxiliaryPosition, 0, false)); + baseList.addAll(getElementsForBreakingSpace(alignment, mapping, mainPosition, + mapping.areaIPD.getOpt(), auxiliaryPosition, 0, false)); } } } - private List getElementsForBreakingSpace(int alignment, AreaInfo areaInfo, Position pos2, + private List getElementsForBreakingSpace(int alignment, GlyphMapping mapping, Position pos2, int p2WidthOffset, Position pos3, int p3WidthOffset, boolean skipZeroCheck) { List elements = new ArrayList(); @@ -1504,7 +1250,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { elements.add(g); elements.add(makeZeroWidthPenalty(0)); g = new KnuthGlue( - areaInfo.areaIPD.getOpt(), + mapping.areaIPD.getOpt(), -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false); elements.add(g); } @@ -1513,25 +1259,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager { case EN_JUSTIFY: // justified text: // the stretch and shrink depends on the space width - elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3, - p3WidthOffset, skipZeroCheck, areaInfo.areaIPD.getShrink())); + elements.addAll(getElementsForJustifiedText(mapping, pos2, p2WidthOffset, pos3, + p3WidthOffset, skipZeroCheck, mapping.areaIPD.getShrink())); break; default: // last line justified, the other lines unjustified: // use only the space stretch - elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3, + elements.addAll(getElementsForJustifiedText(mapping, pos2, p2WidthOffset, pos3, p3WidthOffset, skipZeroCheck, 0)); } return elements; } - private List getElementsForJustifiedText( - AreaInfo areaInfo, Position pos2, int p2WidthOffset, - Position pos3, int p3WidthOffset, boolean skipZeroCheck, - int shrinkability) { + private List getElementsForJustifiedText(GlyphMapping mapping, Position pos2, int p2WidthOffset, + Position pos3, int p3WidthOffset, boolean skipZeroCheck, + int shrinkability) { - int stretchability = areaInfo.areaIPD.getStretch(); + int stretchability = mapping.areaIPD.getStretch(); List elements = new ArrayList(); if (skipZeroCheck || lineStartBAP != 0 || lineEndBAP != 0) { @@ -1543,34 +1288,34 @@ public class TextLayoutManager extends LeafNodeLayoutManager { elements.add(makeZeroWidthPenalty(KnuthElement.INFINITE)); elements.add(new KnuthGlue(lineStartBAP + p3WidthOffset, 0, 0, pos3, false)); } else { - elements.add(new KnuthGlue(areaInfo.areaIPD.getOpt(), stretchability, shrinkability, + elements.add(new KnuthGlue(mapping.areaIPD.getOpt(), stretchability, shrinkability, pos2, false)); } return elements; } - private void addElementsForAWordFragment(List baseList, int alignment, AreaInfo areaInfo, + private void addElementsForAWordFragment(List baseList, int alignment, GlyphMapping mapping, int leafValue) { LeafPosition mainPosition = new LeafPosition(this, leafValue); // if the last character of the word fragment is '-' or '/', // the fragment could end a line; in this case, it loses one // of its letter spaces; - boolean suppressibleLetterSpace = areaInfo.breakOppAfter && !areaInfo.isHyphenated; + boolean suppressibleLetterSpace = mapping.breakOppAfter && !mapping.isHyphenated; if (letterSpaceIPD.isStiff()) { // constant letter spacing baseList.add(new KnuthInlineBox(suppressibleLetterSpace - ? areaInfo.areaIPD.getOpt() - letterSpaceIPD.getOpt() - : areaInfo.areaIPD.getOpt(), + ? mapping.areaIPD.getOpt() - letterSpaceIPD.getOpt() + : mapping.areaIPD.getOpt(), alignmentContext, notifyPos(mainPosition), false)); } else { // adjustable letter spacing int unsuppressibleLetterSpaces = suppressibleLetterSpace - ? areaInfo.letterSpaceCount - 1 - : areaInfo.letterSpaceCount; - baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt() - - areaInfo.letterSpaceCount * letterSpaceIPD.getOpt(), + ? mapping.letterSpaceCount - 1 + : mapping.letterSpaceCount; + baseList.add(new KnuthInlineBox(mapping.areaIPD.getOpt() + - mapping.letterSpaceCount * letterSpaceIPD.getOpt(), alignmentContext, notifyPos(mainPosition), false)); baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE)); baseList.add(new KnuthGlue(letterSpaceIPD.mult(unsuppressibleLetterSpaces), @@ -1580,19 +1325,19 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // extra-elements if the word fragment is the end of a syllable, // or it ends with a character that can be used as a line break - if (areaInfo.isHyphenated) { + if (mapping.isHyphenated) { MinOptMax widthIfNoBreakOccurs = null; - if (areaInfo.breakIndex < foText.length()) { + if (mapping.endIndex < foText.length()) { //Add in kerning in no-break condition - widthIfNoBreakOccurs = letterSpaceAdjustArray[areaInfo.breakIndex]; + widthIfNoBreakOccurs = letterSpaceAdjustArray[mapping.endIndex]; } - //if (areaInfo.breakIndex) + //if (mapping.breakIndex) // the word fragment ends at the end of a syllable: // if a break occurs the content width increases, // otherwise nothing happens addElementsForAHyphen(baseList, alignment, hyphIPD, widthIfNoBreakOccurs, - areaInfo.breakOppAfter && areaInfo.isHyphenated); + mapping.breakOppAfter && mapping.isHyphenated); } else if (suppressibleLetterSpace) { // the word fragment ends with a character that acts as a hyphen // if a break occurs the width does not increase, diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java index 5d89b3440..062a67b38 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -28,16 +28,15 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -47,21 +46,13 @@ import org.apache.fop.traits.SpaceVal; * A list block contains list items which are stacked within * the list block area.. */ -public class ListBlockLayoutManager extends BlockStackingLayoutManager - implements ConditionalElementListener { +public class ListBlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager { /** logging instance */ private static Log log = LogFactory.getLog(ListBlockLayoutManager.class); private Block curBlockArea; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - /** * Create a new list block layout manager. * @param node list-block to create the layout manager for @@ -70,6 +61,11 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager super(node); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getListBlockFO().getCommonBorderPaddingBackground(); + } + /** * Convenience method. * @return the ListBlock node @@ -279,50 +275,5 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager return getListBlockFO().getKeepWithNext(); } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - } diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java index 84dba03ee..773506632 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -32,12 +32,11 @@ import org.apache.fop.area.Block; import org.apache.fop.fo.flow.ListItem; import org.apache.fop.fo.flow.ListItemBody; import org.apache.fop.fo.flow.ListItemLabel; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.BreakOpportunity; import org.apache.fop.layoutmgr.BreakOpportunityHelper; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager; @@ -53,10 +52,9 @@ import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; import org.apache.fop.layoutmgr.SpaceResolver; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; -import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; import org.apache.fop.util.BreakUtil; @@ -64,8 +62,8 @@ import org.apache.fop.util.BreakUtil; * LayoutManager for a list-item FO. * The list item contains a list item label and a list item body. */ -public class ListItemLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener, - BreakOpportunity { +public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** logging instance */ private static Log log = LogFactory.getLog(ListItemLayoutManager.class); @@ -78,13 +76,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements private List<ListElement> labelList = null; private List<ListElement> bodyList = null; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private Keep keepWithNextPendingOnLabel; private Keep keepWithNextPendingOnBody; @@ -145,6 +136,11 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements setBody(node.getBody()); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getListItemFO().getCommonBorderPaddingBackground(); + } + /** * Convenience method. * @return the ListBlock node @@ -475,6 +471,23 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements return returnedList; } + + @Override + public boolean hasLineAreaDescendant() { + return label.hasLineAreaDescendant() || body.hasLineAreaDescendant(); + } + + @Override + public int getBaselineOffset() { + if (label.hasLineAreaDescendant()) { + return label.getBaselineOffset(); + } else if (body.hasLineAreaDescendant()) { + return body.getBaselineOffset(); + } else { + throw newNoLineAreaDescendantException(); + } + } + /** * Add the areas for the break points. * @@ -655,51 +668,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements } /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ @Override public void reset() { super.reset(); diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java index af8e071d5..b2851c1b0 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java @@ -117,6 +117,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager */ public TableCellLayoutManager(TableCell node, PrimaryGridUnit pgu) { super(node); + setGeneratesBlockArea(true); this.primaryGridUnit = pgu; this.isDescendantOfTableHeader = node.getParent().getParent() instanceof TableHeader || node.getParent() instanceof TableHeader; diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java index 7f1754064..afb6547c0 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -39,12 +39,11 @@ import org.apache.fop.fo.flow.Markers; import org.apache.fop.fo.flow.RetrieveTableMarker; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.layoutmgr.BlockLevelEventProducer; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.BreakOpportunity; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.LayoutContext; @@ -52,7 +51,7 @@ import org.apache.fop.layoutmgr.LeafPosition; import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -66,8 +65,8 @@ import org.apache.fop.util.BreakUtil; * The table then creates areas for the columns, bodies and rows * the render background. */ -public class TableLayoutManager extends BlockStackingLayoutManager - implements ConditionalElementListener, BreakOpportunity { +public class TableLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** * logging instance @@ -82,13 +81,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager private double tableUnit; private boolean autoLayout = true; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private int halfBorderSeparationBPD; private int halfBorderSeparationIPD; @@ -132,6 +124,13 @@ public class TableLayoutManager extends BlockStackingLayoutManager this.columns = new ColumnSetup(node); } + + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getTable().getCommonBorderPaddingBackground(); + } + + /** @return the table FO */ public Table getTable() { return (Table)this.fobj; @@ -522,51 +521,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ public void reset() { super.reset(); curBlockArea = null; diff --git a/src/java/org/apache/fop/pdf/PDFProfile.java b/src/java/org/apache/fop/pdf/PDFProfile.java index 6e0cb412e..4ae5ba8df 100644 --- a/src/java/org/apache/fop/pdf/PDFProfile.java +++ b/src/java/org/apache/fop/pdf/PDFProfile.java @@ -169,15 +169,28 @@ public class PDFProfile { * @param context Context information for the user to identify the problem spot */ public void verifyTransparencyAllowed(String context) { - final String err = "{0} does not allow the use of transparency. ({1})"; + Object profile = isTransparencyAllowed(); + if (profile != null) { + throw new PDFConformanceException(profile + " does not allow the use of transparency. (" + + profile + ")"); + } + } + + /** + * Returns {@code null} if transparency is allowed, otherwise returns the profile that + * prevents it. + * + * @return {@code null}, or an object whose {@code toString} method returns the name + * of the profile that disallows transparency + */ + public Object isTransparencyAllowed() { if (pdfAMode.isPart1()) { - throw new PDFConformanceException(MessageFormat.format(err, - new Object[] {getPDFAMode(), context})); + return getPDFAMode(); } if (isPDFXActive()) { - throw new PDFConformanceException(MessageFormat.format(err, - new Object[] {getPDFXMode(), context})); + return getPDFXMode(); } + return null; } /** Checks if the right PDF version is set. */ diff --git a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java index 392eb875e..983a5ad90 100644 --- a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java +++ b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java @@ -31,6 +31,7 @@ import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.dom.AbstractDocument; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.gvt.GraphicsNode; +import org.apache.batik.gvt.font.DefaultFontFamilyResolver; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; @@ -122,7 +123,8 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC //Prepare FOUserAgent userAgent = rendererContext.getUserAgent(); - SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new AffineTransform()); + SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, DefaultFontFamilyResolver.SINGLETON, + new AffineTransform()); //Create Batik BridgeContext final BridgeContext bridgeContext = new BridgeContext(svgUserAgent); diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java index 4549a26af..e05bc007c 100644 --- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java @@ -29,6 +29,7 @@ import org.w3c.dom.Document; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.gvt.GraphicsNode; +import org.apache.batik.gvt.font.DefaultFontFamilyResolver; import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.xmlgraphics.image.loader.ImageSessionContext; @@ -43,6 +44,7 @@ import org.apache.fop.afp.AFPResourceInfo; import org.apache.fop.afp.AFPResourceManager; import org.apache.fop.afp.AFPUnitConverter; import org.apache.fop.afp.svg.AFPBridgeContext; +import org.apache.fop.afp.svg.AFPFontFamilyResolver; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fonts.FontInfo; import org.apache.fop.image.loader.batik.BatikUtil; @@ -53,6 +55,7 @@ import org.apache.fop.render.RendererContext; import org.apache.fop.render.RendererContext.RendererContextWrapper; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; +import org.apache.fop.svg.font.AggregatingFontFamilyResolver; /** * AFP XML handler for SVG. Uses Apache Batik for SVG processing. @@ -196,15 +199,14 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { */ public static BridgeContext createBridgeContext(FOUserAgent userAgent, AFPGraphics2D g2d) { ImageManager imageManager = userAgent.getImageManager(); - - SVGUserAgent svgUserAgent - = new SVGUserAgent(userAgent, new AffineTransform()); - - ImageSessionContext imageSessionContext = userAgent.getImageSessionContext(); - FontInfo fontInfo = g2d.getFontInfo(); + SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, + new AggregatingFontFamilyResolver(new AFPFontFamilyResolver(fontInfo, userAgent.getEventBroadcaster()), + DefaultFontFamilyResolver.SINGLETON), + new AffineTransform()); + ImageSessionContext imageSessionContext = userAgent.getImageSessionContext(); return new AFPBridgeContext(svgUserAgent, fontInfo, imageManager, imageSessionContext, - new AffineTransform(), g2d); + new AffineTransform(), g2d, userAgent.getEventBroadcaster()); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java b/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java index 2f8865b14..5e9372a75 100644 --- a/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java +++ b/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java @@ -21,6 +21,7 @@ package org.apache.fop.render.java2d; import java.awt.Font; import java.awt.FontFormatException; +import java.awt.Rectangle; import java.io.IOException; import java.io.InputStream; import java.util.Map; @@ -183,11 +184,31 @@ public class CustomFontMetricsMapper extends Typeface implements FontMetricsMapp return typeface.getWidths(); } + public Rectangle getBoundingBox(int glyphIndex, int size) { + return typeface.getBoundingBox(glyphIndex, size); + } + /** {@inheritDoc} */ public final int getXHeight(final int size) { return typeface.getXHeight(size); } + public int getUnderlinePosition(int size) { + return typeface.getUnderlinePosition(size); + } + + public int getUnderlineThickness(int size) { + return typeface.getUnderlineThickness(size); + } + + public int getStrikeoutPosition(int size) { + return typeface.getStrikeoutPosition(size); + } + + public int getStrikeoutThickness(int size) { + return typeface.getStrikeoutThickness(size); + } + /** {@inheritDoc} */ public final boolean hasKerningInfo() { return typeface.hasKerningInfo(); diff --git a/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java b/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java index fc4af3574..5e681e9e2 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java +++ b/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java @@ -223,6 +223,26 @@ public class Java2DFontMetrics { return xHeight * 1000; } + public int getUnderlinePosition(String family, int style, int size) { + setFont(family, style, size); + return -Math.round(lineMetrics.getUnderlineOffset()); + } + + public int getUnderlineThickness(String family, int style, int size) { + setFont(family, style, size); + return Math.round(lineMetrics.getUnderlineThickness()); + } + + public int getStrikeoutPosition(String family, int style, int size) { + setFont(family, style, size); + return -Math.round(lineMetrics.getStrikethroughOffset()); + } + + public int getStrikeoutThickness(String family, int style, int size) { + setFont(family, style, size); + return Math.round(lineMetrics.getStrikethroughThickness()); + } + /** * Returns width (in 1/1000ths of point size) of character at * code point i diff --git a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java index 110581f27..f3128c600 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java +++ b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java @@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.gvt.GraphicsNode; +import org.apache.batik.gvt.font.DefaultFontFamilyResolver; import org.apache.fop.image.loader.batik.BatikUtil; import org.apache.fop.render.AbstractGenericSVGHandler; @@ -128,8 +129,8 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler int x = info.currentXPosition; int y = info.currentYPosition; - - SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); + SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), DefaultFontFamilyResolver.SINGLETON, + new AffineTransform()); BridgeContext ctx = new BridgeContext(ua); diff --git a/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java b/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java index 06c975b86..f922e3f05 100644 --- a/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java +++ b/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java @@ -20,6 +20,7 @@ package org.apache.fop.render.java2d; // Java +import java.awt.Rectangle; import java.util.Map; import java.util.Set; @@ -133,6 +134,22 @@ public class SystemFontMetricsMapper extends Typeface implements FontMetricsMapp return java2DFontMetrics.getXHeight(family, style, size); } + public int getUnderlinePosition(int size) { + return java2DFontMetrics.getUnderlinePosition(family, style, size); + } + + public int getUnderlineThickness(int size) { + return java2DFontMetrics.getUnderlineThickness(family, style, size); + } + + public int getStrikeoutPosition(int size) { + return java2DFontMetrics.getStrikeoutPosition(family, style, size); + } + + public int getStrikeoutThickness(int size) { + return java2DFontMetrics.getStrikeoutThickness(family, style, size); + } + /** * {@inheritDoc} */ @@ -148,6 +165,10 @@ public class SystemFontMetricsMapper extends Typeface implements FontMetricsMapp return java2DFontMetrics.getWidths(family, style, Java2DFontMetrics.FONT_SIZE); } + public Rectangle getBoundingBox(int glyphIndex, int size) { + throw new UnsupportedOperationException("Not implemented"); + } + /** * {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java b/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java index 58299c528..471efc567 100644 --- a/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java +++ b/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java @@ -23,6 +23,8 @@ import java.awt.color.ICC_Profile; import java.awt.image.DataBufferByte; import java.awt.image.IndexColorModel; import java.awt.image.Raster; +import java.io.IOException; +import java.util.Arrays; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.logging.Log; @@ -239,24 +241,40 @@ public abstract class AbstractImageAdapter implements PDFImage { + " The image may not be handled correctly." + " Base color space: " + icm.getColorSpace() + " Image: " + image.getInfo()); } - indexed.add(new PDFName(toPDFColorSpace(icm.getColorSpace()).getName())); + ByteArrayOutputStream baout = new ByteArrayOutputStream(); int c = icm.getMapSize(); int hival = c - 1; if (hival > MAX_HIVAL) { throw new UnsupportedOperationException("hival must not go beyond " + MAX_HIVAL); } - indexed.add(Integer.valueOf(hival)); + boolean isDeviceGray = false; int[] palette = new int[c]; icm.getRGBs(palette); - ByteArrayOutputStream baout = new ByteArrayOutputStream(); - for (int i = 0; i < c; i++) { - // TODO Probably doesn't work for non RGB based color spaces - // See log warning above - int entry = palette[i]; - baout.write((entry & 0xFF0000) >> 16); - baout.write((entry & 0xFF00) >> 8); - baout.write(entry & 0xFF); + byte[] reds = new byte[c]; + byte[] greens = new byte[c]; + byte[] blues = new byte[c]; + icm.getReds(reds); + icm.getGreens(greens); + icm.getBlues(blues); + isDeviceGray = Arrays.equals(reds, blues) && Arrays.equals(blues, greens); + if (isDeviceGray) { + indexed.add(new PDFName("DeviceGray")); + try { + baout.write(blues); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + indexed.add(new PDFName(toPDFColorSpace(icm.getColorSpace()).getName())); + for (int i = 0; i < c; i++) { + int entry = palette[i]; + baout.write((entry & 0xFF0000) >> 16); + baout.write((entry & 0xFF00) >> 8); + baout.write(entry & 0xFF); + } } + indexed.add(hival); + indexed.add(baout.toByteArray()); dict.put("ColorSpace", indexed); diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java index a71ade911..5ab0b700f 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java @@ -86,7 +86,7 @@ public class PDFImageHandlerGraphics2D extends AbstractImageHandlerGraphics2D { PDFGraphics2D graphics = new PDFGraphics2D(textAsShapes, pdfContext.getFontInfo(), generator.getDocument(), generator.getResourceContext(), pdfContext.getPage().referencePDF(), - "", 0.0f); + "", 0.0f, null); graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); AffineTransform transform = new AffineTransform(); diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java index 45d8dff2d..ae282f149 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java @@ -41,6 +41,7 @@ import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; import org.apache.xmlgraphics.util.UnitConv; import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.events.EventBroadcaster; import org.apache.fop.image.loader.batik.BatikImageFlavors; import org.apache.fop.image.loader.batik.BatikUtil; import org.apache.fop.render.ImageHandler; @@ -52,6 +53,7 @@ import org.apache.fop.svg.PDFBridgeContext; import org.apache.fop.svg.PDFGraphics2D; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; +import org.apache.fop.svg.font.FOPFontFamilyResolverImpl; /** * Image Handler implementation which handles SVG images. @@ -76,7 +78,8 @@ public class PDFImageHandlerSVG implements ImageHandler { } final float uaResolution = userAgent.getSourceResolution(); - SVGUserAgent ua = new SVGUserAgent(userAgent, new AffineTransform()); + SVGUserAgent ua = new SVGUserAgent(userAgent, new FOPFontFamilyResolverImpl(pdfContext.getFontInfo()), + new AffineTransform()); GVTBuilder builder = new GVTBuilder(); @@ -169,7 +172,7 @@ public class PDFImageHandlerSVG implements ImageHandler { PDFGraphics2D graphics = new PDFGraphics2D(true, pdfContext.getFontInfo(), generator.getDocument(), generator.getResourceContext(), pdfContext.getPage().referencePDF(), - "", 0); + "", 0, new TransparencyIgnoredEventListener(pdfContext, imageSVG)); graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); if (!resolutionScaling.isIdentity()) { @@ -220,6 +223,30 @@ public class PDFImageHandlerSVG implements ImageHandler { } } + private static class TransparencyIgnoredEventListener + implements PDFGraphics2D.TransparencyIgnoredEventListener { + + private final RenderingContext context; + + private final Image image; + + public TransparencyIgnoredEventListener(RenderingContext context, Image image) { + this.context = context; + this.image = image; + } + + private boolean warningIssued; + + public void transparencyIgnored(Object pdfProfile) { + if (!warningIssued) { + EventBroadcaster broadcaster = context.getUserAgent().getEventBroadcaster(); + SVGEventProducer producer = SVGEventProducer.Provider.get(broadcaster); + producer.transparencyIgnored(this, pdfProfile, image.getInfo().getOriginalURI()); + warningIssued = true; + } + } + } + /** {@inheritDoc} */ public int getPriority() { return 400; diff --git a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java index 1d464cae6..96886910e 100644 --- a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java +++ b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java @@ -40,6 +40,7 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.fonts.FontInfo; import org.apache.fop.svg.AbstractFOPTranscoder; import org.apache.fop.svg.PDFDocumentGraphics2DConfigurator; +import org.apache.fop.svg.font.FOPFontFamilyResolverImpl; /** * <p>This class enables to transcode an input to a PostScript document.</p> @@ -115,6 +116,8 @@ public abstract class AbstractPSTranscoder extends AbstractFOPTranscoder { this.fontInfo = PDFDocumentGraphics2DConfigurator.createFontInfo( getEffectiveConfiguration(), useComplexScriptFeatures); graphics.setCustomTextHandler(new NativeTextHandler(graphics, fontInfo)); + ((FOPTranscoderUserAgent) userAgent).setFontFamilyResolver( + new FOPFontFamilyResolverImpl(fontInfo)); } catch (FOPException fe) { throw new TranscoderException(fe); } diff --git a/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java b/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java index cadc28267..4d215926b 100644 --- a/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java +++ b/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java @@ -65,6 +65,7 @@ import org.apache.fop.render.RenderingContext; import org.apache.fop.render.ps.svg.PSSVGGraphics2D; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; +import org.apache.fop.svg.font.FOPFontFamilyResolverImpl; /** * Image handler implementation which handles SVG images for PostScript output. @@ -107,8 +108,8 @@ public class PSImageHandlerSVG implements ImageHandler { boolean strokeText = false; //TODO Configure text stroking - SVGUserAgent ua - = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); + SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), + new FOPFontFamilyResolverImpl(psContext.getFontInfo()), new AffineTransform()); PSSVGGraphics2D graphics = new PSSVGGraphics2D(strokeText, gen); graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); diff --git a/src/java/org/apache/fop/render/ps/PSSVGHandler.java b/src/java/org/apache/fop/render/ps/PSSVGHandler.java index e30f6391b..dfbaf60b7 100644 --- a/src/java/org/apache/fop/render/ps/PSSVGHandler.java +++ b/src/java/org/apache/fop/render/ps/PSSVGHandler.java @@ -249,8 +249,7 @@ public class PSSVGHandler extends AbstractGenericSVGHandler strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText); } - SVGUserAgent ua - = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); + SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), null /* TODO */, new AffineTransform()); PSGraphics2D graphics = new PSGraphics2D(strokeText, gen); graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java index eb2188026..44b7b08a3 100644 --- a/src/java/org/apache/fop/render/ps/PSTextPainter.java +++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java @@ -19,25 +19,21 @@ package org.apache.fop.render.ps; -import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; -import java.awt.geom.Ellipse2D; -import java.awt.geom.GeneralPath; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; +import java.awt.geom.Point2D.Double; import java.io.IOException; -import java.text.AttributedCharacterIterator; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; -import org.apache.batik.gvt.font.GVTGlyphVector; import org.apache.batik.gvt.text.TextPaintInfo; -import org.apache.batik.gvt.text.TextSpanLayout; import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; import org.apache.xmlgraphics.ps.PSGenerator; @@ -48,7 +44,6 @@ import org.apache.fop.fonts.FontMetrics; import org.apache.fop.fonts.LazyFont; import org.apache.fop.fonts.MultiByteFont; import org.apache.fop.svg.NativeTextPainter; -import org.apache.fop.util.CharUtilities; import org.apache.fop.util.HexEncoder; /** @@ -62,10 +57,20 @@ import org.apache.fop.util.HexEncoder; */ public class PSTextPainter extends NativeTextPainter { - private static final boolean DEBUG = false; - private FontResourceCache fontResources; + private PSGraphics2D ps; + + private PSGenerator gen; + + private TextUtil textUtil; + + private boolean flushCurrentRun; + + private PSTextRun psRun; + + private Double relPos; + private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform(); /** @@ -82,165 +87,26 @@ public class PSTextPainter extends NativeTextPainter { return g2d instanceof PSGraphics2D; } - /** {@inheritDoc} */ - protected void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException { - AttributedCharacterIterator runaci = textRun.getACI(); - runaci.first(); - - TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO); - if (tpi == null || !tpi.visible) { - return; - } - if ((tpi != null) && (tpi.composite != null)) { - g2d.setComposite(tpi.composite); - } - - //------------------------------------ - TextSpanLayout layout = textRun.getLayout(); - logTextRun(runaci, layout); - CharSequence chars = collectCharacters(runaci); - runaci.first(); //Reset ACI - - final PSGraphics2D ps = (PSGraphics2D)g2d; - final PSGenerator gen = ps.getPSGenerator(); + @Override + protected void preparePainting(Graphics2D g2d) { + ps = (PSGraphics2D) g2d; + gen = ps.getPSGenerator(); ps.preparePainting(); + } - if (DEBUG) { - log.debug("Text: " + chars); - gen.commentln("%Text: " + chars); - } - - GeneralPath debugShapes = null; - if (DEBUG) { - debugShapes = new GeneralPath(); - } - - TextUtil textUtil = new TextUtil(gen); - textUtil.setupFonts(runaci); - if (!textUtil.hasFonts()) { - //Draw using Java2D when no native fonts are available - textRun.getLayout().draw(g2d); - return; - } - + @Override + protected void saveGraphicsState() throws IOException { gen.saveGraphicsState(); - gen.concatMatrix(g2d.getTransform()); - Shape imclip = g2d.getClip(); - clip(ps, imclip); - - gen.writeln("BT"); //beginTextObject() - - AffineTransform localTransform = new AffineTransform(); - Point2D prevPos = null; - GVTGlyphVector gv = layout.getGlyphVector(); - PSTextRun psRun = new PSTextRun(); //Used to split a text run into smaller runs - for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) { - char ch = chars.charAt(index); - boolean visibleChar = gv.isGlyphVisible(index) - || (CharUtilities.isAnySpace(ch) && !CharUtilities.isZeroWidthSpace(ch)); - logCharacter(ch, layout, index, visibleChar); - if (!visibleChar) { - continue; - } - Point2D glyphPos = gv.getGlyphPosition(index); - - AffineTransform glyphTransform = gv.getGlyphTransform(index); - if (log.isTraceEnabled()) { - log.trace("pos " + glyphPos + ", transform " + glyphTransform); - } - if (DEBUG) { - Shape sh = gv.getGlyphLogicalBounds(index); - if (sh == null) { - sh = new Ellipse2D.Double(glyphPos.getX(), glyphPos.getY(), 2, 2); - } - debugShapes.append(sh, false); - } - - //Exact position of the glyph - localTransform.setToIdentity(); - localTransform.translate(glyphPos.getX(), glyphPos.getY()); - if (glyphTransform != null) { - localTransform.concatenate(glyphTransform); - } - localTransform.scale(1, -1); - - boolean flushCurrentRun = false; - //Try to optimize by combining characters using the same font and on the same line. - if (glyphTransform != null) { - //Happens for text-on-a-path - flushCurrentRun = true; - } - if (psRun.getRunLength() >= 128) { - //Don't let a run get too long - flushCurrentRun = true; - } - - //Note the position of the glyph relative to the previous one - Point2D relPos; - if (prevPos == null) { - relPos = new Point2D.Double(0, 0); - } else { - relPos = new Point2D.Double( - glyphPos.getX() - prevPos.getX(), - glyphPos.getY() - prevPos.getY()); - } - if (psRun.vertChanges == 0 - && psRun.getHorizRunLength() > 2 - && relPos.getY() != 0) { - //new line - flushCurrentRun = true; - } - - //Select the actual character to paint - char paintChar = (CharUtilities.isAnySpace(ch) ? ' ' : ch); - - //Select (sub)font for character - Font f = textUtil.selectFontForChar(paintChar); - char mapped = f.mapChar(ch); - boolean fontChanging = textUtil.isFontChanging(f, mapped); - if (fontChanging) { - flushCurrentRun = true; - } - - if (flushCurrentRun) { - //Paint the current run and reset for the next run - psRun.paint(ps, textUtil, tpi); - psRun.reset(); - } - - //Track current run - psRun.addCharacter(paintChar, relPos); - psRun.noteStartingTransformation(localTransform); - - //Change font if necessary - if (fontChanging) { - textUtil.setCurrentFont(f, mapped); - } + } - //Update last position - prevPos = glyphPos; - } - psRun.paint(ps, textUtil, tpi); - gen.writeln("ET"); //endTextObject() + @Override + protected void restoreGraphicsState() throws IOException { gen.restoreGraphicsState(); - - if (DEBUG) { - //Paint debug shapes - g2d.setStroke(new BasicStroke(0)); - g2d.setColor(Color.LIGHT_GRAY); - g2d.draw(debugShapes); - } } - private void applyColor(Paint paint, final PSGenerator gen) throws IOException { - if (paint == null) { - return; - } else if (paint instanceof Color) { - Color col = (Color)paint; - gen.useColor(col); - } else { - log.warn("Paint not supported: " + paint.toString()); - } + @Override + protected void setInitialTransform(AffineTransform transform) throws IOException { + gen.concatMatrix(transform); } private PSFontResource getResourceForFont(Font f, String postfix) { @@ -248,7 +114,8 @@ public class PSTextPainter extends NativeTextPainter { return this.fontResources.getFontResourceForFontKey(key); } - private void clip(PSGraphics2D ps, Shape shape) throws IOException { + @Override + protected void clip(Shape shape) throws IOException { if (shape == null) { return; } @@ -258,17 +125,76 @@ public class PSTextPainter extends NativeTextPainter { ps.getPSGenerator().writeln("clip"); } + @Override + protected void beginTextObject() throws IOException { + gen.writeln("BT"); + textUtil = new TextUtil(); + psRun = new PSTextRun(); //Used to split a text run into smaller runs + } + + @Override + protected void endTextObject() throws IOException { + psRun.paint(ps, textUtil, tpi); + gen.writeln("ET"); + } + + @Override + protected void positionGlyph(Point2D prevPos, Point2D glyphPos, boolean reposition) { + flushCurrentRun = false; + //Try to optimize by combining characters using the same font and on the same line. + if (reposition) { + //Happens for text-on-a-path + flushCurrentRun = true; + } + if (psRun.getRunLength() >= 128) { + //Don't let a run get too long + flushCurrentRun = true; + } + + //Note the position of the glyph relative to the previous one + if (prevPos == null) { + relPos = new Point2D.Double(0, 0); + } else { + relPos = new Point2D.Double( + glyphPos.getX() - prevPos.getX(), + glyphPos.getY() - prevPos.getY()); + } + if (psRun.vertChanges == 0 + && psRun.getHorizRunLength() > 2 + && relPos.getY() != 0) { + //new line + flushCurrentRun = true; + } + } + + @Override + protected void writeGlyph(char glyph, AffineTransform localTransform) throws IOException { + boolean fontChanging = textUtil.isFontChanging(font, glyph); + if (fontChanging) { + flushCurrentRun = true; + } + + if (flushCurrentRun) { + //Paint the current run and reset for the next run + psRun.paint(ps, textUtil, tpi); + psRun.reset(); + } + + //Track current run + psRun.addGlyph(glyph, relPos); + psRun.noteStartingTransformation(localTransform); + + //Change font if necessary + if (fontChanging) { + textUtil.setCurrentFont(font, glyph); + } + } + private class TextUtil { - private PSGenerator gen; - private Font[] fonts; private Font currentFont; private int currentEncoding = -1; - public TextUtil(PSGenerator gen) { - this.gen = gen; - } - public boolean isMultiByte(Font f) { FontMetrics metrics = f.getFontMetrics(); boolean multiByte = metrics instanceof MultiByteFont || metrics instanceof LazyFont @@ -276,15 +202,6 @@ public class PSTextPainter extends NativeTextPainter { return multiByte; } - public Font selectFontForChar(char ch) { - for (int i = 0, c = fonts.length; i < c; i++) { - if (fonts[i].hasChar(ch)) { - return fonts[i]; - } - } - return fonts[0]; //TODO Maybe fall back to painting with shapes - } - public void writeTextMatrix(AffineTransform transform) throws IOException { double[] matrix = new double[6]; transform.getMatrix(matrix); @@ -335,27 +252,19 @@ public class PSTextPainter extends NativeTextPainter { setCurrentFont(font, encoding); } - public void setupFonts(AttributedCharacterIterator runaci) { - this.fonts = findFonts(runaci); - } - - public boolean hasFonts() { - return (fonts != null) && (fonts.length > 0); - } - } private class PSTextRun { private AffineTransform textTransform; - private List relativePositions = new java.util.LinkedList(); - private StringBuffer currentChars = new StringBuffer(); + private List<Point2D> relativePositions = new LinkedList<Point2D>(); + private StringBuffer currentGlyphs = new StringBuffer(); private int horizChanges = 0; private int vertChanges = 0; public void reset() { textTransform = null; - currentChars.setLength(0); + currentGlyphs.setLength(0); horizChanges = 0; vertChanges = 0; relativePositions.clear(); @@ -369,9 +278,9 @@ public class PSTextPainter extends NativeTextPainter { return 0; } - public void addCharacter(char paintChar, Point2D relPos) { + public void addGlyph(char glyph, Point2D relPos) { addRelativePosition(relPos); - currentChars.append(paintChar); + currentGlyphs.append(glyph); } private void addRelativePosition(Point2D relPos) { @@ -393,7 +302,7 @@ public class PSTextPainter extends NativeTextPainter { } public int getRunLength() { - return currentChars.length(); + return currentGlyphs.length(); } private boolean isXShow() { @@ -407,9 +316,6 @@ public class PSTextPainter extends NativeTextPainter { public void paint(PSGraphics2D g2d, TextUtil textUtil, TextPaintInfo tpi) throws IOException { if (getRunLength() > 0) { - if (log.isDebugEnabled()) { - log.debug("Text run: " + currentChars); - } textUtil.writeTextMatrix(this.textTransform); if (isXShow()) { log.debug("Horizontal text: xshow"); @@ -431,25 +337,20 @@ public class PSTextPainter extends NativeTextPainter { private void paintXYShow(PSGraphics2D g2d, TextUtil textUtil, Paint paint, boolean x, boolean y) throws IOException { - PSGenerator gen = textUtil.gen; - char firstChar = this.currentChars.charAt(0); - //Font only has to be setup up before the first character - Font f = textUtil.selectFontForChar(firstChar); - char mapped = f.mapChar(firstChar); - textUtil.selectFont(f, mapped); - textUtil.setCurrentFont(f, mapped); - applyColor(paint, gen); - - boolean multiByte = textUtil.isMultiByte(f); + char glyph = currentGlyphs.charAt(0); + textUtil.selectFont(font, glyph); + textUtil.setCurrentFont(font, glyph); + applyColor(paint); + + boolean multiByte = textUtil.isMultiByte(font); StringBuffer sb = new StringBuffer(); sb.append(multiByte ? '<' : '('); - for (int i = 0, c = this.currentChars.length(); i < c; i++) { - char ch = this.currentChars.charAt(i); - mapped = f.mapChar(ch); + for (int i = 0, c = this.currentGlyphs.length(); i < c; i++) { + glyph = this.currentGlyphs.charAt(i); if (multiByte) { - sb.append(HexEncoder.encode(mapped)); + sb.append(HexEncoder.encode(glyph)); } else { - char codepoint = (char) (mapped % 256); + char codepoint = (char) (glyph % 256); PSGenerator.escapeChar(codepoint, sb); } } @@ -457,9 +358,9 @@ public class PSTextPainter extends NativeTextPainter { if (x || y) { sb.append("\n["); int idx = 0; - Iterator iter = this.relativePositions.iterator(); + Iterator<Point2D> iter = this.relativePositions.iterator(); while (iter.hasNext()) { - Point2D pt = (Point2D)iter.next(); + Point2D pt = iter.next(); if (idx > 0) { if (x) { sb.append(format(gen, pt.getX())); @@ -500,6 +401,17 @@ public class PSTextPainter extends NativeTextPainter { gen.writeln(sb.toString()); } + private void applyColor(Paint paint) throws IOException { + if (paint == null) { + return; + } else if (paint instanceof Color) { + Color col = (Color) paint; + gen.useColor(col); + } else { + log.warn("Paint not supported: " + paint.toString()); + } + } + private String format(PSGenerator gen, double coord) { if (Math.abs(coord) < 0.00001) { return "0"; @@ -510,30 +422,21 @@ public class PSTextPainter extends NativeTextPainter { private void paintStrokedGlyphs(PSGraphics2D g2d, TextUtil textUtil, Paint strokePaint, Stroke stroke) throws IOException { - PSGenerator gen = textUtil.gen; - - applyColor(strokePaint, gen); + applyColor(strokePaint); PSGraphics2D.applyStroke(stroke, gen); - Font f = null; - Iterator iter = this.relativePositions.iterator(); + Iterator<Point2D> iter = this.relativePositions.iterator(); iter.next(); Point2D pos = new Point2D.Double(0, 0); gen.writeln("0 0 M"); - for (int i = 0, c = this.currentChars.length(); i < c; i++) { - char ch = this.currentChars.charAt(0); + for (int i = 0, c = this.currentGlyphs.length(); i < c; i++) { + char mapped = this.currentGlyphs.charAt(i); if (i == 0) { - //Font only has to be setup up before the first character - f = textUtil.selectFontForChar(ch); - } - char mapped = f.mapChar(ch); - if (i == 0) { - textUtil.selectFont(f, mapped); - textUtil.setCurrentFont(f, mapped); + textUtil.selectFont(font, mapped); + textUtil.setCurrentFont(font, mapped); } //add glyph outlines to current path - mapped = f.mapChar(this.currentChars.charAt(i)); - FontMetrics metrics = f.getFontMetrics(); + FontMetrics metrics = font.getFontMetrics(); boolean multiByte = metrics instanceof MultiByteFont || metrics instanceof LazyFont && ((LazyFont) metrics).getRealFont() instanceof MultiByteFont; @@ -542,14 +445,14 @@ public class PSTextPainter extends NativeTextPainter { gen.write(HexEncoder.encode(mapped)); gen.write(">"); } else { - char codepoint = (char)(mapped % 256); + char codepoint = (char) (mapped % 256); gen.write("(" + codepoint + ")"); } gen.writeln(" false charpath"); if (iter.hasNext()) { //Position for the next character - Point2D pt = (Point2D)iter.next(); + Point2D pt = iter.next(); pos.setLocation(pos.getX() + pt.getX(), pos.getY() - pt.getY()); gen.writeln(gen.formatDouble5(pos.getX()) + " " + gen.formatDouble5(pos.getY()) + " M"); diff --git a/src/java/org/apache/fop/render/rtf/RTFHandler.java b/src/java/org/apache/fop/render/rtf/RTFHandler.java index 73fa3504c..2bb7befc1 100644 --- a/src/java/org/apache/fop/render/rtf/RTFHandler.java +++ b/src/java/org/apache/fop/render/rtf/RTFHandler.java @@ -218,8 +218,10 @@ public class RTFHandler extends FOEventHandler { eventProducer.onlySPMSupported(this, reference, pageSeq.getLocator()); PageSequenceMaster master = pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(reference); - this.pagemaster = master.getNextSimplePageMaster( - false, false, false, false, pageSeq.getMainFlow().getFlowName()); + if (pageSeq.getMainFlow() != null) { + this.pagemaster = master.getNextSimplePageMaster( + false, false, false, false, pageSeq.getMainFlow().getFlowName()); + } } } diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfStringConverter.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfStringConverter.java index bf32eceeb..9f542dd75 100644 --- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfStringConverter.java +++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfStringConverter.java @@ -102,7 +102,7 @@ public final class RtfStringConverter { if (i != 0) { d = new Character(str.charAt(i - 1)); } else { - d = new Character(str.charAt(i)); + d = new Character(SPACE); } //This section modified by Chris Scott diff --git a/src/java/org/apache/fop/svg/ACIUtils.java b/src/java/org/apache/fop/svg/ACIUtils.java index f54a026e1..deba98f21 100644 --- a/src/java/org/apache/fop/svg/ACIUtils.java +++ b/src/java/org/apache/fop/svg/ACIUtils.java @@ -38,7 +38,8 @@ import org.apache.batik.gvt.text.GVTAttributedCharacterIterator; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontTriplet; +import org.apache.fop.svg.font.FOPGVTFont; +import org.apache.fop.svg.font.FOPGVTFontFamily; /** * Utilities for java.text.AttributedCharacterIterator. @@ -64,57 +65,43 @@ public final class ACIUtils { @SuppressWarnings("unchecked") List<GVTFontFamily> gvtFonts = (List<GVTFontFamily>) aci.getAttribute( GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES); - Float posture = (Float) aci.getAttribute(TextAttribute.POSTURE); - Float taWeight = (Float) aci.getAttribute(TextAttribute.WEIGHT); - Float fontSize = (Float) aci.getAttribute(TextAttribute.SIZE); - - String style = toStyle(posture); - int weight = toCSSWeight(taWeight); - int fsize = (int)(fontSize.floatValue() * 1000); + String style = toStyle((Float) aci.getAttribute(TextAttribute.POSTURE)); + int weight = toCSSWeight((Float) aci.getAttribute(TextAttribute.WEIGHT)); + float fontSize = ((Float) aci.getAttribute(TextAttribute.SIZE)).floatValue(); String firstFontFamily = null; - //GVT_FONT can sometimes be different from the fonts in GVT_FONT_FAMILIES //or GVT_FONT_FAMILIES can even be empty and only GVT_FONT is set - /* The following code section is not available until Batik 1.7 is released. */ - GVTFont gvtFont = (GVTFont)aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.GVT_FONT); + GVTFont gvtFont = (GVTFont) aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT); if (gvtFont != null) { String gvtFontFamily = gvtFont.getFamilyName(); - if (fontInfo.hasFont(gvtFontFamily, style, weight)) { - FontTriplet triplet = fontInfo.fontLookup(gvtFontFamily, style, - weight); - Font f = fontInfo.getFontInstance(triplet, fsize); + if (gvtFont instanceof FOPGVTFont) { + Font font = ((FOPGVTFont) gvtFont).getFont(); if (LOG.isDebugEnabled()) { LOG.debug("Found a font that matches the GVT font: " + gvtFontFamily + ", " + weight + ", " + style - + " -> " + f); + + " -> " + font); } - fonts.add(f); + fonts.add(font); } firstFontFamily = gvtFontFamily; } if (gvtFonts != null) { boolean haveInstanceOfSVGFontFamily = false; - for (GVTFontFamily fam : gvtFonts) { - if (fam instanceof SVGFontFamily) { + for (GVTFontFamily fontFamily : gvtFonts) { + if (fontFamily instanceof SVGFontFamily) { haveInstanceOfSVGFontFamily = true; - } - String fontFamily = fam.getFamilyName(); - if (fontInfo.hasFont(fontFamily, style, weight)) { - FontTriplet triplet = fontInfo.fontLookup(fontFamily, style, - weight); - Font f = fontInfo.getFontInstance(triplet, fsize); + } else if (fontFamily instanceof FOPGVTFontFamily) { + Font font = ((FOPGVTFontFamily) fontFamily).deriveFont(fontSize, aci).getFont(); if (LOG.isDebugEnabled()) { LOG.debug("Found a font that matches the GVT font family: " - + fontFamily + ", " + weight + ", " + style - + " -> " + f); + + fontFamily.getFamilyName() + ", " + weight + ", " + style + " -> " + font); } - fonts.add(f); + fonts.add(font); } if (firstFontFamily == null) { - firstFontFamily = fontFamily; + firstFontFamily = fontFamily.getFamilyName(); } } // SVG fonts are embedded fonts in the SVG document and are rarely used; however if they @@ -126,25 +113,10 @@ public final class ACIUtils { return null; // Let Batik paint this text! } } - if (fonts.isEmpty()) { - if (firstFontFamily == null) { - //This will probably never happen. Just to be on the safe side. - firstFontFamily = "any"; - } - //lookup with fallback possibility (incl. substitution notification) - FontTriplet triplet = fontInfo.fontLookup(firstFontFamily, style, weight); - Font f = fontInfo.getFontInstance(triplet, fsize); - if (LOG.isDebugEnabled()) { - LOG.debug("Falling back to adjustable font lookup up for: " - + firstFontFamily + ", " + weight + ", " + style - + " -> " + f); - } - fonts.add(f); - } - return fonts.toArray(new Font[fonts.size()]); + return fonts.isEmpty() ? null : fonts.toArray(new Font[fonts.size()]); } - private static int toCSSWeight(Float weight) { + public static int toCSSWeight(Float weight) { if (weight == null) { return 400; } else if (weight <= TextAttribute.WEIGHT_EXTRA_LIGHT.floatValue()) { @@ -170,7 +142,7 @@ public final class ACIUtils { } } - private static String toStyle(Float posture) { + public static String toStyle(Float posture) { return ((posture != null) && (posture.floatValue() > 0.0)) ? Font.STYLE_ITALIC : Font.STYLE_NORMAL; diff --git a/src/java/org/apache/fop/svg/AbstractFOPTextPainter.java b/src/java/org/apache/fop/svg/AbstractFOPTextPainter.java index 3e16799f4..7df127d3a 100644 --- a/src/java/org/apache/fop/svg/AbstractFOPTextPainter.java +++ b/src/java/org/apache/fop/svg/AbstractFOPTextPainter.java @@ -23,20 +23,15 @@ import java.awt.Color; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.Shape; -import java.awt.font.TextAttribute; -import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.text.AttributedCharacterIterator; import java.text.CharacterIterator; -import java.util.Iterator; -import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.batik.dom.svg.SVGOMTextElement; import org.apache.batik.gvt.TextNode; import org.apache.batik.gvt.TextPainter; import org.apache.batik.gvt.renderer.StrokingTextPainter; @@ -66,15 +61,15 @@ public abstract class AbstractFOPTextPainter implements TextPainter { * Use the stroking text painter to get the bounds and shape. * Also used as a fallback to draw the string with strokes. */ - protected static final TextPainter - PROXY_PAINTER = StrokingTextPainter.getInstance(); + private final TextPainter proxyTextPainter; /** * Create a new PS text painter with the given font information. * @param nativeTextHandler the NativeTextHandler instance used for text painting */ - public AbstractFOPTextPainter(FOPTextHandler nativeTextHandler) { + public AbstractFOPTextPainter(FOPTextHandler nativeTextHandler, TextPainter proxyTextPainter) { this.nativeTextHandler = nativeTextHandler; + this.proxyTextPainter = proxyTextPainter; } /** @@ -85,19 +80,10 @@ public abstract class AbstractFOPTextPainter implements TextPainter { * @param g2d the Graphics2D to use */ public void paint(TextNode node, Graphics2D g2d) { - Point2D loc = node.getLocation(); - if (!isSupportedGraphics2D(g2d) || hasUnsupportedAttributes(node)) { - if (log.isDebugEnabled()) { - log.debug("painting text node " + node - + " by stroking due to unsupported attributes or an incompatible Graphics2D"); - } - PROXY_PAINTER.paint(node, g2d); - } else { - if (log.isDebugEnabled()) { - log.debug("painting text node " + node + " normally."); - } - paintTextRuns(node.getTextRuns(), g2d, loc); + if (isSupportedGraphics2D(g2d)) { + new TextRunPainter().paintTextRuns(node.getTextRuns(), g2d, node.getLocation()); } + proxyTextPainter.paint(node, g2d); } /** @@ -109,190 +95,99 @@ public abstract class AbstractFOPTextPainter implements TextPainter { */ protected abstract boolean isSupportedGraphics2D(Graphics2D g2d); - private boolean hasUnsupportedAttributes(TextNode node) { - Iterator iter = node.getTextRuns().iterator(); - while (iter.hasNext()) { - StrokingTextPainter.TextRun - run = (StrokingTextPainter.TextRun)iter.next(); - AttributedCharacterIterator aci = run.getACI(); - boolean hasUnsupported = hasUnsupportedAttributes(aci); - if (hasUnsupported) { - return true; - } - } - return false; - } - - private boolean hasUnsupportedAttributes(AttributedCharacterIterator aci) { - boolean hasUnsupported = false; - - Font font = getFont(aci); - String text = getText(aci); - if (hasUnsupportedGlyphs(text, font)) { - log.trace("-> Unsupported glyphs found"); - hasUnsupported = true; - } + private class TextRunPainter { - TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO); - if ((tpi != null) - && ((tpi.strokeStroke != null && tpi.strokePaint != null) - || (tpi.strikethroughStroke != null) - || (tpi.underlineStroke != null) - || (tpi.overlineStroke != null))) { - log.trace("-> under/overlines etc. found"); - hasUnsupported = true; - } + private Point2D currentLocation; - //Alpha is not supported - Paint foreground = (Paint) aci.getAttribute(TextAttribute.FOREGROUND); - if (foreground instanceof Color) { - Color col = (Color)foreground; - if (col.getAlpha() != 255) { - log.trace("-> transparency found"); - hasUnsupported = true; + public void paintTextRuns(Iterable<StrokingTextPainter.TextRun> textRuns, Graphics2D g2d, + Point2D nodeLocation) { + currentLocation = new Point2D.Double(nodeLocation.getX(), nodeLocation.getY()); + for (StrokingTextPainter.TextRun run : textRuns) { + paintTextRun(run, g2d); } } - Object letSpace = aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.LETTER_SPACING); - if (letSpace != null) { - log.trace("-> letter spacing found"); - hasUnsupported = true; - } - - Object wordSpace = aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING); - if (wordSpace != null) { - log.trace("-> word spacing found"); - hasUnsupported = true; - } - - Object lengthAdjust = aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.LENGTH_ADJUST); - if (lengthAdjust != null) { - log.trace("-> length adjustments found"); - hasUnsupported = true; - } - - Object writeMod = aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE); - if (writeMod != null - && !GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals( - writeMod)) { - log.trace("-> Unsupported writing modes found"); - hasUnsupported = true; - } - - Object vertOr = aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION); - if (GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_ANGLE.equals( - vertOr)) { - log.trace("-> vertical orientation found"); - hasUnsupported = true; - } - - Object rcDel = aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER); - //Batik 1.6 returns null here which makes it impossible to determine whether this can - //be painted or not, i.e. fall back to stroking. :-( - if (rcDel != null && !(rcDel instanceof SVGOMTextElement)) { - log.trace("-> spans found"); - hasUnsupported = true; //Filter spans - } - - if (hasUnsupported) { - log.trace("Unsupported attributes found in ACI, using StrokingTextPainter"); - } - return hasUnsupported; - } - - /** - * Paint a list of text runs on the Graphics2D at a given location. - * @param textRuns the list of text runs - * @param g2d the Graphics2D to paint to - * @param loc the current location of the "cursor" - */ - protected void paintTextRuns(List textRuns, Graphics2D g2d, Point2D loc) { - Point2D currentloc = loc; - Iterator i = textRuns.iterator(); - while (i.hasNext()) { - StrokingTextPainter.TextRun - run = (StrokingTextPainter.TextRun)i.next(); - currentloc = paintTextRun(run, g2d, currentloc); - } - } - - /** - * Paint a single text run on the Graphics2D at a given location. - * @param run the text run to paint - * @param g2d the Graphics2D to paint to - * @param loc the current location of the "cursor" - * @return the new location of the "cursor" after painting the text run - */ - protected Point2D paintTextRun(StrokingTextPainter.TextRun run, Graphics2D g2d, Point2D loc) { - AttributedCharacterIterator aci = run.getACI(); - aci.first(); - - updateLocationFromACI(aci, loc); - AffineTransform at = g2d.getTransform(); - loc = at.transform(loc, null); - - // font - Font font = getFont(aci); - if (font != null) { - nativeTextHandler.setOverrideFont(font); - } - - // color - TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO); - if (tpi == null) { - return loc; - } - Paint foreground = tpi.fillPaint; - if (foreground instanceof Color) { - Color col = (Color)foreground; - g2d.setColor(col); - } - g2d.setPaint(foreground); - - // text anchor - TextNode.Anchor anchor = (TextNode.Anchor)aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE); - - // text - String txt = getText(aci); - float advance = getStringWidth(txt, font); - float tx = 0; - if (anchor != null) { - switch (anchor.getType()) { - case TextNode.Anchor.ANCHOR_MIDDLE: - tx = -advance / 2; - break; - case TextNode.Anchor.ANCHOR_END: - tx = -advance; - break; - default: //nop + private void paintTextRun(StrokingTextPainter.TextRun run, Graphics2D g2d) { + AttributedCharacterIterator aci = run.getACI(); + aci.first(); + updateLocationFromACI(aci, currentLocation); + // font + Font font = getFont(aci); + if (font != null) { + nativeTextHandler.setOverrideFont(font); } - } - - // draw string - double x = loc.getX(); - double y = loc.getY(); - try { + // color + TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO); + if (tpi == null) { + return; + } + Paint foreground = tpi.fillPaint; + if (foreground instanceof Color) { + Color col = (Color) foreground; + g2d.setColor(col); + } + g2d.setPaint(foreground); + // text anchor + TextNode.Anchor anchor = (TextNode.Anchor) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE); + // text + String txt = getText(aci); + double advance = font == null ? run.getLayout().getAdvance2D().getX() : getStringWidth(txt, font); + double tx = 0; + if (anchor != null) { + switch (anchor.getType()) { + case TextNode.Anchor.ANCHOR_MIDDLE: + tx = -advance / 2; + break; + case TextNode.Anchor.ANCHOR_END: + tx = -advance; + break; + default: //nop + } + } + // draw string + Point2D outputLocation = g2d.getTransform().transform(currentLocation, null); + double x = outputLocation.getX(); + double y = outputLocation.getY(); try { - nativeTextHandler.drawString(g2d, txt, (float)x + tx, (float)y); - } catch (IOException ioe) { - if (g2d instanceof AFPGraphics2D) { - ((AFPGraphics2D)g2d).handleIOException(ioe); + try { + //TODO draw underline and overline if set + nativeTextHandler.drawString(g2d, txt, (float) (x + tx), (float) y); + //TODO draw strikethrough if set + } catch (IOException ioe) { + if (g2d instanceof AFPGraphics2D) { + ((AFPGraphics2D) g2d).handleIOException(ioe); + } } + } finally { + nativeTextHandler.setOverrideFont(null); + } + currentLocation.setLocation(currentLocation.getX() + advance, currentLocation.getY()); + } + private void updateLocationFromACI(AttributedCharacterIterator aci, Point2D loc) { + //Adjust position of span + Float xpos = (Float) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.X); + Float ypos = (Float) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.Y); + Float dxpos = (Float) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.DX); + Float dypos = (Float) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.DY); + if (xpos != null) { + loc.setLocation(xpos.doubleValue(), loc.getY()); + } + if (ypos != null) { + loc.setLocation(loc.getX(), ypos.doubleValue()); + } + if (dxpos != null) { + loc.setLocation(loc.getX() + dxpos.doubleValue(), loc.getY()); + } + if (dypos != null) { + loc.setLocation(loc.getX(), loc.getY() + dypos.doubleValue()); } - } finally { - nativeTextHandler.setOverrideFont(null); } - loc.setLocation(loc.getX() + advance, loc.getY()); - return loc; } /** @@ -305,36 +200,9 @@ public abstract class AbstractFOPTextPainter implements TextPainter { for (char c = aci.first(); c != CharacterIterator.DONE; c = aci.next()) { sb.append(c); } - aci.first(); return sb.toString(); } - private void updateLocationFromACI( - AttributedCharacterIterator aci, - Point2D loc) { - //Adjust position of span - Float xpos = (Float)aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.X); - Float ypos = (Float)aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.Y); - Float dxpos = (Float)aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.DX); - Float dypos = (Float)aci.getAttribute( - GVTAttributedCharacterIterator.TextAttribute.DY); - if (xpos != null) { - loc.setLocation(xpos.doubleValue(), loc.getY()); - } - if (ypos != null) { - loc.setLocation(loc.getX(), ypos.doubleValue()); - } - if (dxpos != null) { - loc.setLocation(loc.getX() + dxpos.doubleValue(), loc.getY()); - } - if (dypos != null) { - loc.setLocation(loc.getX(), loc.getY() + dypos.doubleValue()); - } - } - private Font getFont(AttributedCharacterIterator aci) { Font[] fonts = ACIUtils.findFontsForBatikACI(aci, nativeTextHandler.getFontInfo()); return fonts == null ? null : fonts[0]; @@ -360,21 +228,6 @@ public abstract class AbstractFOPTextPainter implements TextPainter { return wordWidth / 1000f; } - private boolean hasUnsupportedGlyphs(String str, Font font) { - if (font == null) { - return true; - } - for (int i = 0; i < str.length(); i++) { - char c = str.charAt(i); - if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) { - if (!font.hasChar(c)) { - return true; - } - } - } - return false; - } - /** * Get the outline shape of the text characters. * This uses the StrokingTextPainter to get the outline @@ -384,7 +237,7 @@ public abstract class AbstractFOPTextPainter implements TextPainter { * @return the outline shape of the text characters */ public Shape getOutline(TextNode node) { - return PROXY_PAINTER.getOutline(node); + return proxyTextPainter.getOutline(node); } /** @@ -399,7 +252,7 @@ public abstract class AbstractFOPTextPainter implements TextPainter { /* (todo) getBounds2D() is too slow * because it uses the StrokingTextPainter. We should implement this * method ourselves. */ - return PROXY_PAINTER.getBounds2D(node); + return proxyTextPainter.getBounds2D(node); } /** @@ -411,7 +264,7 @@ public abstract class AbstractFOPTextPainter implements TextPainter { * @return the bounds of the text */ public Rectangle2D getGeometryBounds(TextNode node) { - return PROXY_PAINTER.getGeometryBounds(node); + return proxyTextPainter.getGeometryBounds(node); } // Methods that have no purpose for PS diff --git a/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java b/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java index e04bf0d35..9b1606953 100644 --- a/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java +++ b/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java @@ -36,9 +36,9 @@ import org.apache.avalon.framework.configuration.DefaultConfiguration; import org.apache.commons.logging.Log; import org.apache.commons.logging.impl.SimpleLog; -import org.apache.batik.bridge.UserAgent; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.dom.util.DocumentFactory; +import org.apache.batik.gvt.font.FontFamilyResolver; import org.apache.batik.transcoder.ErrorHandler; import org.apache.batik.transcoder.SVGAbstractTranscoder; import org.apache.batik.transcoder.TranscoderException; @@ -56,6 +56,8 @@ import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext; import org.apache.xmlgraphics.util.UnitConv; +import org.apache.fop.svg.font.FOPFontFamilyResolver; + /** * This is the common base class of all of FOP's transcoders. */ @@ -86,11 +88,6 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem /** The value to turn off text stroking. */ public static final Boolean VALUE_FORMAT_OFF = Boolean.FALSE; - /** - * The user agent dedicated to this Transcoder. - */ - protected UserAgent userAgent = createUserAgent(); - private Log logger; private EntityResolver resolver; private Configuration cfg = null; @@ -113,7 +110,7 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem * this method if you need non-default behaviour. * @return UserAgent the newly created user agent */ - protected UserAgent createUserAgent() { + protected FOPTranscoderUserAgent createUserAgent() { return new FOPTranscoderUserAgent(); } @@ -331,6 +328,8 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem */ protected class FOPTranscoderUserAgent extends SVGAbstractTranscoderUserAgent { + private FOPFontFamilyResolver fontFamilyResolver; + /** * Displays the specified error message using the {@link ErrorHandler}. * @param message the message to display @@ -386,6 +385,15 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem return "print"; } + public void setFontFamilyResolver(FOPFontFamilyResolver resolver) { + fontFamilyResolver = resolver; + } + + @Override + public FontFamilyResolver getFontFamilyResolver() { + return fontFamilyResolver; + } + } } diff --git a/src/java/org/apache/fop/svg/NativeTextPainter.java b/src/java/org/apache/fop/svg/NativeTextPainter.java index 4513e0101..200f6558b 100644 --- a/src/java/org/apache/fop/svg/NativeTextPainter.java +++ b/src/java/org/apache/fop/svg/NativeTextPainter.java @@ -19,7 +19,14 @@ package org.apache.fop.svg; +import java.awt.BasicStroke; +import java.awt.Color; import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Ellipse2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; import java.io.IOException; import java.text.AttributedCharacterIterator; import java.util.List; @@ -27,11 +34,17 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.batik.bridge.SVGGVTFont; +import org.apache.batik.gvt.font.FontFamilyResolver; +import org.apache.batik.gvt.font.GVTGlyphVector; import org.apache.batik.gvt.renderer.StrokingTextPainter; +import org.apache.batik.gvt.text.TextPaintInfo; import org.apache.batik.gvt.text.TextSpanLayout; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.svg.font.FOPFontFamilyResolverImpl; +import org.apache.fop.svg.font.FOPGVTFont; import org.apache.fop.util.CharUtilities; /** @@ -41,17 +54,26 @@ import org.apache.fop.util.CharUtilities; public abstract class NativeTextPainter extends StrokingTextPainter { /** the logger for this class */ - protected Log log = LogFactory.getLog(NativeTextPainter.class); + protected static final Log log = LogFactory.getLog(NativeTextPainter.class); + + private static final boolean DEBUG = false; /** the font collection */ protected final FontInfo fontInfo; + protected final FontFamilyResolver fontFamilyResolver; + + protected Font font; + + protected TextPaintInfo tpi; + /** * Creates a new instance. * @param fontInfo the font collection */ public NativeTextPainter(FontInfo fontInfo) { this.fontInfo = fontInfo; + this.fontFamilyResolver = new FOPFontFamilyResolverImpl(fontInfo); } /** @@ -68,11 +90,93 @@ public abstract class NativeTextPainter extends StrokingTextPainter { * @param g2d the target Graphics2D instance * @throws IOException if an I/O error occurs while rendering the text */ - protected abstract void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException; + protected final void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException { + AttributedCharacterIterator runaci = textRun.getACI(); + runaci.first(); + + tpi = (TextPaintInfo) runaci.getAttribute(PAINT_INFO); + if (tpi == null || !tpi.visible) { + return; + } + if (tpi.composite != null) { + g2d.setComposite(tpi.composite); + } + + //------------------------------------ + TextSpanLayout layout = textRun.getLayout(); + logTextRun(runaci, layout); + runaci.first(); //Reset ACI + + GeneralPath debugShapes = null; + if (DEBUG) { + debugShapes = new GeneralPath(); + } + + preparePainting(g2d); + + GVTGlyphVector gv = layout.getGlyphVector(); + if (!(gv.getFont() instanceof FOPGVTFont)) { + assert gv.getFont() == null || gv.getFont() instanceof SVGGVTFont; + //Draw using Java2D when no native fonts are available + textRun.getLayout().draw(g2d); + return; + } + font = ((FOPGVTFont) gv.getFont()).getFont(); + + saveGraphicsState(); + setInitialTransform(g2d.getTransform()); + clip(g2d.getClip()); + beginTextObject(); + + AffineTransform localTransform = new AffineTransform(); + Point2D prevPos = null; + AffineTransform prevGlyphTransform = null; + for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) { + if (!gv.isGlyphVisible(index)) { + continue; + } + Point2D glyphPos = gv.getGlyphPosition(index); + + AffineTransform glyphTransform = gv.getGlyphTransform(index); + if (log.isTraceEnabled()) { + log.trace("pos " + glyphPos + ", transform " + glyphTransform); + } + if (DEBUG) { + Shape sh = gv.getGlyphLogicalBounds(index); + if (sh == null) { + sh = new Ellipse2D.Double(glyphPos.getX(), glyphPos.getY(), 2, 2); + } + debugShapes.append(sh, false); + } + + //Exact position of the glyph + localTransform.setToIdentity(); + localTransform.translate(glyphPos.getX(), glyphPos.getY()); + if (glyphTransform != null) { + localTransform.concatenate(glyphTransform); + } + localTransform.scale(1, -1); + + positionGlyph(prevPos, glyphPos, glyphTransform != null || prevGlyphTransform != null); + char glyph = (char) gv.getGlyphCode(index); + //Update last position + prevPos = glyphPos; + prevGlyphTransform = glyphTransform; + + writeGlyph(glyph, localTransform); + } + endTextObject(); + restoreGraphicsState(); + if (DEBUG) { + //Paint debug shapes + g2d.setStroke(new BasicStroke(0)); + g2d.setColor(Color.LIGHT_GRAY); + g2d.draw(debugShapes); + } + } - /** {@inheritDoc} */ @Override - protected void paintTextRuns(List textRuns, Graphics2D g2d) { + protected void paintTextRuns(@SuppressWarnings("rawtypes") List textRuns, Graphics2D g2d) { if (log.isTraceEnabled()) { log.trace("paintTextRuns: count = " + textRuns.size()); } @@ -81,7 +185,7 @@ public abstract class NativeTextPainter extends StrokingTextPainter { return; } for (int i = 0; i < textRuns.size(); i++) { - TextRun textRun = (TextRun)textRuns.get(i); + TextRun textRun = (TextRun) textRuns.get(i); try { paintTextRun(textRun, g2d); } catch (IOException ioe) { @@ -92,16 +196,6 @@ public abstract class NativeTextPainter extends StrokingTextPainter { } /** - * Finds an array of suitable fonts for a given AttributedCharacterIterator. - * @param aci the character iterator - * @return the array of fonts - */ - protected Font[] findFonts(AttributedCharacterIterator aci) { - Font[] fonts = ACIUtils.findFontsForBatikACI(aci, fontInfo); - return fonts; - } - - /** * Collects all characters from an {@link AttributedCharacterIterator}. * @param runaci the character iterator * @return the characters @@ -115,6 +209,25 @@ public abstract class NativeTextPainter extends StrokingTextPainter { return chars; } + protected abstract void preparePainting(Graphics2D g2d); + + protected abstract void saveGraphicsState() throws IOException; + + protected abstract void restoreGraphicsState() throws IOException; + + protected abstract void setInitialTransform(AffineTransform transform) throws IOException; + + protected abstract void clip(Shape clip) throws IOException; + + protected abstract void beginTextObject() throws IOException; + + protected abstract void endTextObject() throws IOException; + + protected abstract void positionGlyph(Point2D prevPos, Point2D glyphPos, boolean reposition); + + protected abstract void writeGlyph(char glyph, AffineTransform transform) throws IOException; + + /** * @param runaci an attributed character iterator * @param layout a text span layout @@ -155,5 +268,9 @@ public abstract class NativeTextPainter extends StrokingTextPainter { } } + @Override + protected FontFamilyResolver getFontFamilyResolver() { + return this.fontFamilyResolver; + } } diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java index 1fcf9f870..42d79a931 100644 --- a/src/java/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java @@ -189,6 +189,17 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand */ protected OutputStream outputStream = null; + private TransparencyIgnoredEventListener transparencyIgnoredEventListener; + + /** + * May be used to give proper feedback to the user when a particular PDF profile is + * being used that disallows transparency. + */ + public interface TransparencyIgnoredEventListener { + + void transparencyIgnored(Object pdfProfile); + } + /** * Create a new PDFGraphics2D with the given pdf document info. * This is used to create a Graphics object for use inside an already @@ -203,7 +214,8 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand * @param size the current font size */ public PDFGraphics2D(boolean textAsShapes, FontInfo fi, PDFDocument doc, - PDFResourceContext page, String pref, String font, float size) { + PDFResourceContext page, String pref, String font, float size, + TransparencyIgnoredEventListener listener) { this(textAsShapes); pdfDoc = doc; this.colorHandler = new PDFColorHandler(doc.getResources()); @@ -213,6 +225,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand fontInfo = fi; pageRef = pref; paintingState = new PDFPaintingState(); + this.transparencyIgnoredEventListener = listener; } /** @@ -244,6 +257,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand this.nativeCount = g.nativeCount; this.outputStream = g.outputStream; this.ovFontState = g.ovFontState; + this.transparencyIgnoredEventListener = g.transparencyIgnoredEventListener; } /** @@ -977,7 +991,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand PDFResourceContext context = new PDFResourceContext(res); PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, specialFontInfo, pdfDoc, context, getPageReference(), - "", 0); + "", 0, transparencyIgnoredEventListener); pattGraphic.setGraphicContext(new GraphicContext()); pattGraphic.gc.validateTransformStack(); pattGraphic.setRenderingHints(this.getRenderingHints()); @@ -1430,18 +1444,21 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand */ protected void applyAlpha(int fillAlpha, int strokeAlpha) { if (fillAlpha != OPAQUE || strokeAlpha != OPAQUE) { - checkTransparencyAllowed(); - Map<String, Float> vals = new java.util.HashMap<String, Float>(); - if (fillAlpha != OPAQUE) { - vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(fillAlpha / 255f)); - } - if (strokeAlpha != OPAQUE) { - vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f)); + Object profile = isTransparencyAllowed(); + if (profile == null) { + Map<String, Float> vals = new java.util.HashMap<String, Float>(); + if (fillAlpha != OPAQUE) { + vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(fillAlpha / 255f)); + } + if (strokeAlpha != OPAQUE) { + vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f)); + } + PDFGState gstate = pdfDoc.getFactory().makeGState(vals, paintingState.getGState()); + resourceContext.addGState(gstate); + currentStream.write("/" + gstate.getName() + " gs\n"); + } else if (transparencyIgnoredEventListener != null) { + transparencyIgnoredEventListener.transparencyIgnored(profile); } - PDFGState gstate = pdfDoc.getFactory().makeGState( - vals, paintingState.getGState()); - resourceContext.addGState(gstate); - currentStream.write("/" + gstate.getName() + " gs\n"); } } @@ -1686,8 +1703,8 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand } /** Checks whether the use of transparency is allowed. */ - protected void checkTransparencyAllowed() { - pdfDoc.getProfile().verifyTransparencyAllowed("Java2D graphics"); + protected Object isTransparencyAllowed() { + return pdfDoc.getProfile().isTransparencyAllowed(); } /** diff --git a/src/java/org/apache/fop/svg/PDFTextPainter.java b/src/java/org/apache/fop/svg/PDFTextPainter.java index ef376663f..c5fa9f04e 100644 --- a/src/java/org/apache/fop/svg/PDFTextPainter.java +++ b/src/java/org/apache/fop/svg/PDFTextPainter.java @@ -19,25 +19,17 @@ package org.apache.fop.svg; -import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; -import java.awt.geom.Ellipse2D; -import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; -import java.text.AttributedCharacterIterator; -import org.apache.batik.gvt.font.GVTGlyphVector; import org.apache.batik.gvt.text.TextPaintInfo; -import org.apache.batik.gvt.text.TextSpanLayout; -import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; -import org.apache.fop.util.CharUtilities; /** * Renders the attributed character iterator of a {@link org.apache.batik.gvt.TextNode}. @@ -51,11 +43,19 @@ import org.apache.fop.util.CharUtilities; */ class PDFTextPainter extends NativeTextPainter { - private static final boolean DEBUG = false; + private PDFGraphics2D pdf; + + private PDFTextUtil textUtil; + + private double prevVisibleGlyphWidth; + + private boolean repositionNextGlyph; /** * Create a new PDF text painter with the given font information. + * * @param fi the font info + * @param fontFamilyResolver the Font Family Resolver */ public PDFTextPainter(FontInfo fi) { super(fi); @@ -67,29 +67,29 @@ class PDFTextPainter extends NativeTextPainter { return g2d instanceof PDFGraphics2D; } - /** {@inheritDoc} */ @Override - protected void paintTextRun(TextRun textRun, Graphics2D g2d) { - AttributedCharacterIterator runaci = textRun.getACI(); - runaci.first(); + protected void preparePainting(Graphics2D g2d) { + pdf = (PDFGraphics2D) g2d; + } - TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO); - if (tpi == null || !tpi.visible) { - return; - } - if ((tpi != null) && (tpi.composite != null)) { - g2d.setComposite(tpi.composite); - } + @Override + protected void saveGraphicsState() { + pdf.saveGraphicsState(); + } - //------------------------------------ - TextSpanLayout layout = textRun.getLayout(); - logTextRun(runaci, layout); - CharSequence chars = collectCharacters(runaci); - runaci.first(); //Reset ACI + @Override + protected void restoreGraphicsState() { + pdf.restoreGraphicsState(); + } - final PDFGraphics2D pdf = (PDFGraphics2D)g2d; + @Override + protected void setInitialTransform(AffineTransform transform) { + createTextUtil(); + textUtil.concatMatrix(transform); + } - PDFTextUtil textUtil = new PDFTextUtil(pdf.fontInfo) { + private void createTextUtil() { + textUtil = new PDFTextUtil(pdf.fontInfo) { protected void write(String code) { pdf.currentStream.write(code); } @@ -97,142 +97,39 @@ class PDFTextPainter extends NativeTextPainter { pdf.currentStream.append(code); } }; + } - if (DEBUG) { - log.debug("Text: " + chars); - pdf.currentStream.write("%Text: " + chars + "\n"); - } - - GeneralPath debugShapes = null; - if (DEBUG) { - debugShapes = new GeneralPath(); - } - - Font[] fonts = findFonts(runaci); - if (fonts == null || fonts.length == 0) { - //Draw using Java2D when no native fonts are available - textRun.getLayout().draw(g2d); - return; - } - - pdf.saveGraphicsState(); - textUtil.concatMatrix(g2d.getTransform()); - Shape imclip = g2d.getClip(); - pdf.writeClip(imclip); - - applyColorAndPaint(tpi, pdf); + @Override + protected void clip(Shape clip) { + pdf.writeClip(clip); + } + @Override + protected void beginTextObject() { + applyColorAndPaint(tpi); textUtil.beginTextObject(); - textUtil.setFonts(fonts); - boolean stroke = (tpi.strokePaint != null) - && (tpi.strokeStroke != null); + boolean stroke = (tpi.strokePaint != null) && (tpi.strokeStroke != null); textUtil.setTextRenderingMode(tpi.fillPaint != null, stroke, false); + } - AffineTransform localTransform = new AffineTransform(); - Point2D prevPos = null; - double prevVisibleCharWidth = 0.0; - GVTGlyphVector gv = layout.getGlyphVector(); - for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) { - char ch = chars.charAt(index); - boolean visibleChar = gv.isGlyphVisible(index) - || (CharUtilities.isAnySpace(ch) && !CharUtilities.isZeroWidthSpace(ch)); - logCharacter(ch, layout, index, visibleChar); - if (!visibleChar) { - continue; - } - Point2D glyphPos = gv.getGlyphPosition(index); - - AffineTransform glyphTransform = gv.getGlyphTransform(index); - //TODO Glyph transforms could be refined so not every char has to be painted - //with its own TJ command (stretch/squeeze case could be optimized) - if (log.isTraceEnabled()) { - log.trace("pos " + glyphPos + ", transform " + glyphTransform); - } - if (DEBUG) { - Shape sh = gv.getGlyphLogicalBounds(index); - if (sh == null) { - sh = new Ellipse2D.Double(glyphPos.getX(), glyphPos.getY(), 2, 2); - } - debugShapes.append(sh, false); - } - - //Exact position of the glyph - localTransform.setToIdentity(); - localTransform.translate(glyphPos.getX(), glyphPos.getY()); - if (glyphTransform != null) { - localTransform.concatenate(glyphTransform); - } - localTransform.scale(1, -1); - - boolean yPosChanged = (prevPos == null - || prevPos.getY() != glyphPos.getY() - || glyphTransform != null); - if (yPosChanged) { - if (index > 0) { - textUtil.writeTJ(); - textUtil.writeTextMatrix(localTransform); - } - } else { - double xdiff = glyphPos.getX() - prevPos.getX(); - //Width of previous character - Font font = textUtil.getCurrentFont(); - double cw = prevVisibleCharWidth; - double effxdiff = (1000 * xdiff) - cw; - if (effxdiff != 0) { - double adjust = (-effxdiff / font.getFontSize()); - textUtil.adjustGlyphTJ(adjust * 1000); - } - if (log.isTraceEnabled()) { - log.trace("==> x diff: " + xdiff + ", " + effxdiff - + ", charWidth: " + cw); - } - } - Font f = textUtil.selectFontForChar(ch); - char paintChar = (CharUtilities.isAnySpace(ch) ? ' ' : ch); - char mappedChar = f.mapChar(paintChar); - boolean encodingChanging = false; // used for single byte - if (!textUtil.isMultiByteFont(f.getFontName())) { - int encoding = mappedChar / 256; - mappedChar = (char) (mappedChar % 256); - if (textUtil.getCurrentEncoding() != encoding) { - textUtil.setCurrentEncoding(encoding); - encodingChanging = true; - } - } - if (f != textUtil.getCurrentFont() || encodingChanging) { - textUtil.writeTJ(); - textUtil.setCurrentFont(f); - textUtil.writeTf(f); - textUtil.writeTextMatrix(localTransform); - } - textUtil.writeTJMappedChar(mappedChar); - - //Update last position - prevPos = glyphPos; - prevVisibleCharWidth = textUtil.getCurrentFont().getCharWidth(chars.charAt(index)); - } + @Override + protected void endTextObject() { textUtil.writeTJ(); textUtil.endTextObject(); - pdf.restoreGraphicsState(); - if (DEBUG) { - g2d.setStroke(new BasicStroke(0)); - g2d.setColor(Color.LIGHT_GRAY); - g2d.draw(debugShapes); - } } - private void applyColorAndPaint(TextPaintInfo tpi, PDFGraphics2D pdf) { + private void applyColorAndPaint(TextPaintInfo tpi) { Paint fillPaint = tpi.fillPaint; Paint strokePaint = tpi.strokePaint; Stroke stroke = tpi.strokeStroke; int fillAlpha = PDFGraphics2D.OPAQUE; if (fillPaint instanceof Color) { - Color col = (Color)fillPaint; + Color col = (Color) fillPaint; pdf.applyColor(col, true); fillAlpha = col.getAlpha(); } if (strokePaint instanceof Color) { - Color col = (Color)strokePaint; + Color col = (Color) strokePaint; pdf.applyColor(col, false); } pdf.applyPaint(fillPaint, true); @@ -243,4 +140,46 @@ class PDFTextPainter extends NativeTextPainter { pdf.applyAlpha(fillAlpha, PDFGraphics2D.OPAQUE); } + @Override + protected void positionGlyph(Point2D prevPos, Point2D glyphPos, boolean reposition) { + // TODO Glyph transforms could be refined so not every char has to be painted + // with its own TJ command (stretch/squeeze case could be optimized) + repositionNextGlyph = (prevPos == null + || prevPos.getY() != glyphPos.getY() + || reposition); + if (!repositionNextGlyph) { + double xdiff = glyphPos.getX() - prevPos.getX(); + //Width of previous character + double cw = prevVisibleGlyphWidth; + double effxdiff = (1000 * xdiff) - cw; + if (effxdiff != 0) { + double adjust = (-effxdiff / font.getFontSize()); + textUtil.adjustGlyphTJ(adjust * 1000); + } + } + } + + @Override + protected void writeGlyph(char glyph, AffineTransform transform) { + prevVisibleGlyphWidth = font.getWidth(glyph); + boolean encodingChanging = false; // used for single byte + if (!textUtil.isMultiByteFont(font.getFontName())) { + int encoding = glyph / 256; + glyph = (char) (glyph % 256); + if (textUtil.getCurrentEncoding() != encoding) { + textUtil.setCurrentEncoding(encoding); + encodingChanging = true; + } + } + if (repositionNextGlyph || encodingChanging) { + textUtil.writeTJ(); + if (font != textUtil.getCurrentFont() || encodingChanging) { + textUtil.setCurrentFont(font); + textUtil.writeTf(font); + } + textUtil.writeTextMatrix(transform); + } + textUtil.writeTJMappedChar(glyph); + } + } diff --git a/src/java/org/apache/fop/svg/PDFTextUtil.java b/src/java/org/apache/fop/svg/PDFTextUtil.java index 8325dce1f..d525ecefc 100644 --- a/src/java/org/apache/fop/svg/PDFTextUtil.java +++ b/src/java/org/apache/fop/svg/PDFTextUtil.java @@ -30,7 +30,6 @@ import org.apache.fop.fonts.Typeface; public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil { private FontInfo fontInfo; - private Font[] fonts; private Font font; private int encoding; @@ -50,23 +49,6 @@ public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil { } /** - * Sets the current fonts for the text object. For every character, the suitable font will - * be selected. - * @param fonts the new fonts - */ - public void setFonts(Font[] fonts) { - this.fonts = fonts; - } - - /** - * Sets the current font for the text object. - * @param font the new font - */ - public void setFont(Font font) { - setFonts(new Font[] {font}); - } - - /** * Returns the current font in use. * @return the current font or null if no font is currently active. */ @@ -123,27 +105,4 @@ public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil { } } - /** - * Selects a font from the font list suitable to display the given character. - * @param ch the character - * @return the recommended Font to use - */ - public Font selectFontForChar(char ch) { - for (int i = 0, c = fonts.length; i < c; i++) { - if (fonts[i].hasChar(ch)) { - return fonts[i]; - } - } - return fonts[0]; //TODO Maybe fall back to painting with shapes - } - - /** - * Writes a char to the "TJ-Buffer". - * @param ch the unmapped character - */ - public void writeTJChar(char ch) { - char mappedChar = font.mapChar(ch); - writeTJMappedChar(mappedChar); - } - } diff --git a/src/java/org/apache/fop/svg/PDFTranscoder.java b/src/java/org/apache/fop/svg/PDFTranscoder.java index 9f0345657..1a3f154cb 100644 --- a/src/java/org/apache/fop/svg/PDFTranscoder.java +++ b/src/java/org/apache/fop/svg/PDFTranscoder.java @@ -31,7 +31,6 @@ import org.apache.avalon.framework.configuration.Configuration; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.UnitProcessor; -import org.apache.batik.bridge.UserAgent; import org.apache.batik.ext.awt.RenderingHintsKeyExt; import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderOutput; @@ -39,6 +38,7 @@ import org.apache.batik.transcoder.image.ImageTranscoder; import org.apache.fop.Version; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.svg.font.FOPFontFamilyResolverImpl; /** * <p>This class enables to transcode an input to a PDF document.</p> @@ -88,7 +88,7 @@ public class PDFTranscoder extends AbstractFOPTranscoder { /** * {@inheritDoc} */ - protected UserAgent createUserAgent() { + protected FOPTranscoderUserAgent createUserAgent() { return new AbstractFOPTranscoder.FOPTranscoderUserAgent() { // The PDF stuff wants everything at 72dpi public float getPixelUnitToMillimeter() { @@ -131,6 +131,8 @@ public class PDFTranscoder extends AbstractFOPTranscoder { } else { graphics.setupDefaultFontInfo(); } + ((FOPTranscoderUserAgent) userAgent).setFontFamilyResolver( + new FOPFontFamilyResolverImpl(graphics.getFontInfo())); } catch (Exception e) { throw new TranscoderException( "Error while setting up PDFDocumentGraphics2D", e); diff --git a/src/java/org/apache/fop/svg/SVGEventProducer.java b/src/java/org/apache/fop/svg/SVGEventProducer.java index 743649717..6bf7ed100 100644 --- a/src/java/org/apache/fop/svg/SVGEventProducer.java +++ b/src/java/org/apache/fop/svg/SVGEventProducer.java @@ -89,4 +89,13 @@ public interface SVGEventProducer extends EventProducer { */ void svgRenderingError(Object source, Exception e, String uri); + /** + * Transparency has been ignored due to restrictions from the PDF profile being used. + * @param source the event source + * @param pdfProfile the PDF profile + * @param uri the image URI, if available + * @event.severity WARN + */ + void transparencyIgnored(Object source, Object pdfProfile, String uri); + } diff --git a/src/java/org/apache/fop/svg/SVGEventProducer.xml b/src/java/org/apache/fop/svg/SVGEventProducer.xml index 9d229a14b..f5e1d300a 100644 --- a/src/java/org/apache/fop/svg/SVGEventProducer.xml +++ b/src/java/org/apache/fop/svg/SVGEventProducer.xml @@ -22,4 +22,5 @@ <message key="info">SVG info: {message}</message> <message key="svgNotBuilt">SVG graphic could not be built. Reason: {e}</message> <message key="svgRenderingError">SVG graphic could not be rendered. Reason: {e}</message> + <message key="transparencyIgnored">Transparency in an SVG image will be ignored because {pdfProfile} does not allow it[ (see {uri})].</message> </catalogue> diff --git a/src/java/org/apache/fop/svg/SVGUserAgent.java b/src/java/org/apache/fop/svg/SVGUserAgent.java index d43552289..a265b4fef 100644 --- a/src/java/org/apache/fop/svg/SVGUserAgent.java +++ b/src/java/org/apache/fop/svg/SVGUserAgent.java @@ -21,6 +21,8 @@ package org.apache.fop.svg; import java.awt.geom.AffineTransform; +import org.apache.batik.gvt.font.FontFamilyResolver; + import org.apache.fop.apps.FOUserAgent; /** @@ -34,10 +36,11 @@ public class SVGUserAgent extends SimpleSVGUserAgent { /** * Creates a new SVGUserAgent. * @param foUserAgent the FO user agent to associate with this SVG user agent + * @param fontFamilyResolver the font family resolver * @param at the current transform */ - public SVGUserAgent(FOUserAgent foUserAgent, AffineTransform at) { - super(foUserAgent.getSourcePixelUnitToMillimeter(), at); + public SVGUserAgent(FOUserAgent foUserAgent, FontFamilyResolver fontFamilyResolver, AffineTransform at) { + super(foUserAgent.getSourcePixelUnitToMillimeter(), at, fontFamilyResolver); this.eventProducer = SVGEventProducer.Provider.get(foUserAgent.getEventBroadcaster()); } @@ -45,8 +48,8 @@ public class SVGUserAgent extends SimpleSVGUserAgent { * Creates a new SVGUserAgent. * @param foUserAgent the FO user agent to associate with this SVG user agent */ - public SVGUserAgent(FOUserAgent foUserAgent) { - this(foUserAgent, new AffineTransform()); + public SVGUserAgent(FOUserAgent foUserAgent, FontFamilyResolver fontFamilyResolver) { + this(foUserAgent, fontFamilyResolver, new AffineTransform()); } /** diff --git a/src/java/org/apache/fop/svg/SimpleSVGUserAgent.java b/src/java/org/apache/fop/svg/SimpleSVGUserAgent.java index 132c633dc..60a6020fc 100644 --- a/src/java/org/apache/fop/svg/SimpleSVGUserAgent.java +++ b/src/java/org/apache/fop/svg/SimpleSVGUserAgent.java @@ -29,6 +29,7 @@ import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import org.apache.batik.bridge.UserAgentAdapter; +import org.apache.batik.gvt.font.FontFamilyResolver; /** * A simple SVG user agent. @@ -38,14 +39,18 @@ import org.apache.batik.bridge.UserAgentAdapter; public class SimpleSVGUserAgent extends UserAgentAdapter { private AffineTransform currentTransform = null; + private float pixelUnitToMillimeter = 0.0f; + private final FontFamilyResolver fontFamilyResolver; + /** * Creates a new user agent. * @param pixelUnitToMM the pixel to millimeter conversion factor currently in effect * @param at the current transform */ - public SimpleSVGUserAgent(float pixelUnitToMM, AffineTransform at) { + public SimpleSVGUserAgent(float pixelUnitToMM, AffineTransform at, FontFamilyResolver fontFamilyResolver) { + this.fontFamilyResolver = fontFamilyResolver; pixelUnitToMillimeter = pixelUnitToMM; currentTransform = at; } @@ -136,5 +141,10 @@ public class SimpleSVGUserAgent extends UserAgentAdapter { return new Dimension(100, 100); } + @Override + public FontFamilyResolver getFontFamilyResolver() { + return fontFamilyResolver; + } + } diff --git a/src/java/org/apache/fop/svg/font/AggregatingFontFamilyResolver.java b/src/java/org/apache/fop/svg/font/AggregatingFontFamilyResolver.java new file mode 100644 index 000000000..a5a25c4ce --- /dev/null +++ b/src/java/org/apache/fop/svg/font/AggregatingFontFamilyResolver.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +import org.apache.batik.bridge.FontFace; +import org.apache.batik.gvt.font.FontFamilyResolver; +import org.apache.batik.gvt.font.GVTFontFamily; + +public class AggregatingFontFamilyResolver implements FontFamilyResolver { + + private final List<FontFamilyResolver> resolvers; + + public AggregatingFontFamilyResolver(FontFamilyResolver... resolvers) { + this.resolvers = Arrays.<FontFamilyResolver>asList(resolvers); + } + + public GVTFontFamily resolve(String familyName) { + for (FontFamilyResolver resolver : resolvers) { + GVTFontFamily family = resolver.resolve(familyName); + if (family != null) { + return family; + } + } + return null; + } + + public GVTFontFamily resolve(String familyName, FontFace fontFace) { + for (FontFamilyResolver resolver : resolvers) { + GVTFontFamily family = resolver.resolve(familyName, fontFace); + if (family != null) { + return family; + } + } + return null; + } + + public GVTFontFamily loadFont(InputStream in, FontFace fontFace) throws Exception { + for (FontFamilyResolver resolver : resolvers) { + try { + return resolver.loadFont(in, fontFace); + } catch (Exception e) { + // Try the next one + } + } + return null; + } + + public GVTFontFamily getDefault() { + return resolve("any"); + } + + public GVTFontFamily getFamilyThatCanDisplay(char c) { + for (FontFamilyResolver resolver : resolvers) { + GVTFontFamily family = resolver.getFamilyThatCanDisplay(c); + if (family != null) { + return family; + } + } + return null; + } + +} diff --git a/src/java/org/apache/fop/svg/font/FOPFontFamilyResolver.java b/src/java/org/apache/fop/svg/font/FOPFontFamilyResolver.java new file mode 100644 index 000000000..7af5f0b4f --- /dev/null +++ b/src/java/org/apache/fop/svg/font/FOPFontFamilyResolver.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import org.apache.batik.gvt.font.FontFamilyResolver; + +public interface FOPFontFamilyResolver extends FontFamilyResolver { + + FOPGVTFontFamily resolve(String familyName); + + FOPGVTFontFamily getDefault(); + + FOPGVTFontFamily getFamilyThatCanDisplay(char c); +} diff --git a/src/java/org/apache/fop/svg/font/FOPFontFamilyResolverImpl.java b/src/java/org/apache/fop/svg/font/FOPFontFamilyResolverImpl.java new file mode 100644 index 000000000..4305838da --- /dev/null +++ b/src/java/org/apache/fop/svg/font/FOPFontFamilyResolverImpl.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.io.InputStream; +import java.util.Map; + +import org.apache.batik.bridge.FontFace; +import org.apache.batik.gvt.font.GVTFontFace; +import org.apache.batik.gvt.font.GVTFontFamily; + +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontTriplet; +import org.apache.fop.fonts.Typeface; + +public class FOPFontFamilyResolverImpl implements FOPFontFamilyResolver { + + private final FontInfo fontInfo; + + public FOPFontFamilyResolverImpl(FontInfo fontInfo) { + this.fontInfo = fontInfo; + } + + public FOPGVTFontFamily resolve(String familyName) { + return resolve(familyName, new GVTFontFace(familyName)); + } + + public FOPGVTFontFamily resolve(String familyName, FontFace fontFace) { + return resolve(familyName, (GVTFontFace) FontFace.createFontFace(familyName, fontFace)); + } + + private FOPGVTFontFamily resolve(String familyName, GVTFontFace fontFace) { + FOPGVTFontFamily gvtFontFamily = null; + FontTriplet triplet = fontInfo.fontLookup(familyName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + if (fontInfo.hasFont(familyName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL)) { + gvtFontFamily = new FOPGVTFontFamily(fontInfo, familyName, triplet, fontFace); + } + return gvtFontFamily; + } + + public GVTFontFamily loadFont(InputStream in, FontFace fontFace) throws Exception { + throw new UnsupportedOperationException("Not implemented"); + } + + public FOPGVTFontFamily getDefault() { + return resolve("any"); + } + + public FOPGVTFontFamily getFamilyThatCanDisplay(char c) { + Map<String, Typeface> fonts = fontInfo.getFonts(); + for (Typeface font : fonts.values()) { + if (font.hasChar(c)) { + String fontFamily = font.getFamilyNames().iterator().next(); + return new FOPGVTFontFamily(fontInfo, fontFamily, + new FontTriplet(fontFamily, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL), + new GVTFontFace(fontFamily)); + } + } + return null; + } + +} diff --git a/src/java/org/apache/fop/svg/font/FOPGVTFont.java b/src/java/org/apache/fop/svg/font/FOPGVTFont.java new file mode 100644 index 000000000..c55e2fa8b --- /dev/null +++ b/src/java/org/apache/fop/svg/font/FOPGVTFont.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.awt.font.FontRenderContext; +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; + +import org.apache.batik.gvt.font.GVTFont; +import org.apache.batik.gvt.font.GVTFontFamily; +import org.apache.batik.gvt.font.GVTGlyphVector; +import org.apache.batik.gvt.font.GVTLineMetrics; + +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontMetrics; + +public class FOPGVTFont implements GVTFont { + + private final Font font; + + private final GVTFontFamily fontFamily; + + public FOPGVTFont(Font font, GVTFontFamily fontFamily) { + this.font = font; + this.fontFamily = fontFamily; + } + + public Font getFont() { + return font; + } + + public boolean canDisplay(char c) { + return font.hasChar(c); + } + + public int canDisplayUpTo(char[] text, int start, int limit) { + for (int i = start; i < limit; i++) { + if (!canDisplay(text[i])) { + return i; + } + } + return -1; + } + + + public int canDisplayUpTo(CharacterIterator iter, int start, int limit) { + for (char c = iter.setIndex(start); iter.getIndex() < limit; c = iter.next()) { + if (!canDisplay(c)) { + return iter.getIndex(); + } + } + return -1; + } + + public int canDisplayUpTo(String str) { + for (int i = 0; i < str.length(); i++) { + if (!canDisplay(str.charAt(i))) { + return i; + } + } + return -1; + } + + public GVTGlyphVector createGlyphVector(FontRenderContext frc, char[] chars) { + return createGlyphVector(frc, new String(chars)); + } + + public GVTGlyphVector createGlyphVector(FontRenderContext frc, CharacterIterator ci) { + // TODO Batik does manual glyph shaping for Arabic. Replace with complex scripts implementation + return new FOPGVTGlyphVector(this, ci, frc); + } + + public GVTGlyphVector createGlyphVector(FontRenderContext frc, + int[] glyphCodes, + CharacterIterator ci) { + throw new UnsupportedOperationException("Not implemented"); + } + + public GVTGlyphVector createGlyphVector(FontRenderContext frc, String str) { + StringCharacterIterator sci = new StringCharacterIterator(str); + return createGlyphVector(frc, sci); + } + + public FOPGVTFont deriveFont(float size) { + throw new UnsupportedOperationException("Not implemented"); + } + + public String getFamilyName() { + return fontFamily.getFamilyName(); + } + + public GVTLineMetrics getLineMetrics(char[] chars, int beginIndex, int limit, FontRenderContext frc) { + return getLineMetrics(limit - beginIndex); + } + + GVTLineMetrics getLineMetrics(int numChars) { + numChars = numChars < 0 ? 0 : numChars; + FontMetrics metrics = font.getFontMetrics(); + int size = font.getFontSize(); + return new GVTLineMetrics( + metrics.getCapHeight(size) / 1000000f, + java.awt.Font.ROMAN_BASELINE, // Not actually used by Batik + null, // Not actually used by Batik + -metrics.getDescender(size) / 1000000f, + 0, // Not actually used by Batik + 0, // Not actually used by Batik + numChars, + -metrics.getStrikeoutPosition(size) / 1000000f, + metrics.getStrikeoutThickness(size) / 1000000f, + -metrics.getUnderlinePosition(size) / 1000000f, + metrics.getUnderlineThickness(size) / 1000000f, + -metrics.getCapHeight(size) / 1000000f, // Because this is what Batik does in GVTLineMetrics + metrics.getUnderlineThickness(size) / 1000000f); + } + + public GVTLineMetrics getLineMetrics(CharacterIterator ci, int beginIndex, int limit, + FontRenderContext frc) { + return getLineMetrics(limit - beginIndex); + } + + public GVTLineMetrics getLineMetrics(String str, FontRenderContext frc) { + return getLineMetrics(str.length()); + } + + public GVTLineMetrics getLineMetrics(String str, int beginIndex, int limit, FontRenderContext frc) { + return getLineMetrics(limit - beginIndex); + } + + public float getSize() { + return font.getFontSize() / 1000f; + } + + public float getVKern(int glyphCode1, int glyphCode2) { + return 0; + } + + public float getHKern(int glyphCode1, int glyphCode2) { + // TODO Cannot be implemented until getKernValue takes glyph indices instead of character codes + return 0; + } + +} diff --git a/src/java/org/apache/fop/svg/font/FOPGVTFontFamily.java b/src/java/org/apache/fop/svg/font/FOPGVTFontFamily.java new file mode 100644 index 000000000..5be9419d3 --- /dev/null +++ b/src/java/org/apache/fop/svg/font/FOPGVTFontFamily.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.awt.font.TextAttribute; +import java.text.AttributedCharacterIterator; +import java.util.Map; + +import org.apache.batik.gvt.font.GVTFontFace; +import org.apache.batik.gvt.font.GVTFontFamily; + +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontTriplet; +import org.apache.fop.svg.ACIUtils; + +public class FOPGVTFontFamily implements GVTFontFamily { + + private final FontInfo fontInfo; + + private final FontTriplet fontTriplet; + + private final String familyName; + + private GVTFontFace fontFace; + + public FOPGVTFontFamily(FontInfo fontInfo, String familyName, FontTriplet triplet, GVTFontFace fontFace) { + this.fontInfo = fontInfo; + this.fontTriplet = triplet; + this.familyName = familyName; + this.fontFace = fontFace; + } + + public String getFamilyName() { + return familyName; + } + + public GVTFontFace getFontFace() { + return fontFace; + } + + public FOPGVTFont deriveFont(float size, AttributedCharacterIterator aci) { + return deriveFont(size, aci.getAttributes()); + } + + public FOPGVTFont deriveFont(float size, @SuppressWarnings("rawtypes") Map attrs) { + Float fontWeight = (Float) attrs.get(TextAttribute.WEIGHT); + int weight = fontWeight == null ? fontTriplet.getWeight() : ACIUtils.toCSSWeight(fontWeight); + Float fontStyle = (Float) attrs.get(TextAttribute.POSTURE); + String style = fontStyle == null ? fontTriplet.getStyle() : ACIUtils.toStyle(fontStyle); + FontTriplet triplet = fontInfo.fontLookup(fontTriplet.getName(), style, weight); + return new FOPGVTFont(fontInfo.getFontInstance(triplet, (int) (size * 1000)), this); + } + + public boolean isComplex() { + return false; + } + +} diff --git a/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java b/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java new file mode 100644 index 000000000..3567bb508 --- /dev/null +++ b/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java @@ -0,0 +1,339 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphJustificationInfo; +import java.awt.font.GlyphMetrics; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.text.AttributedCharacterIterator; +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.Arrays; + +import org.apache.batik.gvt.font.GVTFont; +import org.apache.batik.gvt.font.GVTGlyphMetrics; +import org.apache.batik.gvt.font.GVTGlyphVector; +import org.apache.batik.gvt.font.GVTLineMetrics; + +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontMetrics; +import org.apache.fop.fonts.GlyphMapping; +import org.apache.fop.fonts.TextFragment; +import org.apache.fop.traits.MinOptMax; + +class FOPGVTGlyphVector implements GVTGlyphVector { + + private final CharacterIterator charIter; + + private final FOPGVTFont font; + + private final int fontSize; + + private final FontMetrics fontMetrics; + + private final FontRenderContext frc; + + private int[] glyphs; + + private float[] positions; + + private Rectangle2D[] boundingBoxes; + + private GeneralPath outline; + + private AffineTransform[] glyphTransforms; + + private boolean[] glyphVisibilities; + + private Rectangle2D logicalBounds; + + FOPGVTGlyphVector(FOPGVTFont font, final CharacterIterator iter, FontRenderContext frc) { + this.charIter = iter; + this.font = font; + Font f = font.getFont(); + this.fontSize = f.getFontSize(); + this.fontMetrics = f.getFontMetrics(); + this.frc = frc; + } + + public void performDefaultLayout() { + Font f = font.getFont(); + TextFragment text = new SVGTextFragment(charIter); + MinOptMax letterSpaceIPD = MinOptMax.ZERO; + MinOptMax[] letterSpaceAdjustments = new MinOptMax[charIter.getEndIndex() - charIter.getBeginIndex()]; + GlyphMapping mapping = GlyphMapping.doGlyphMapping(text, charIter.getBeginIndex(), charIter.getEndIndex(), + f, letterSpaceIPD, letterSpaceAdjustments, '\0', '\0', false, 0 /* TODO */); + glyphs = buildGlyphs(f, mapping.mapping != null ? new StringCharacterIterator(mapping.mapping) : charIter); + buildGlyphPositions(mapping, letterSpaceAdjustments); + this.glyphVisibilities = new boolean[this.glyphs.length]; + Arrays.fill(glyphVisibilities, true); + this.glyphTransforms = new AffineTransform[this.glyphs.length]; + } + + private static class SVGTextFragment implements TextFragment { + + private final CharacterIterator charIter; + + SVGTextFragment(CharacterIterator charIter) { + this.charIter = charIter; + } + + public CharSequence subSequence(int startIndex, int endIndex) { + StringBuilder sb = new StringBuilder(); + for (char c = charIter.first(); c != CharacterIterator.DONE; c = charIter.next()) { + sb.append(c); + } + return sb.toString(); + } + + public String getScript() { + return "DFLT"; // TODO pass on script value from SVG + } + + public String getLanguage() { + return "dflt"; // TODO pass on language value from SVG + } + + public char charAt(int index) { + return charIter.setIndex(index - charIter.getBeginIndex()); + } + } + + private int[] buildGlyphs(Font font, final CharacterIterator charIter) { + int[] glyphs = new int[charIter.getEndIndex() - charIter.getBeginIndex()]; + int index = 0; + for (char c = charIter.first(); c != CharacterIterator.DONE; c = charIter.next()) { + glyphs[index] = font.mapChar(c); + index++; + } + return glyphs; + } + + private void buildGlyphPositions(GlyphMapping ai, MinOptMax[] letterSpaceAdjustments) { + positions = new float[2 * glyphs.length + 2]; + if (ai.gposAdjustments != null) { + assert ai.gposAdjustments.length == glyphs.length; + for (int glyphIndex = 0; glyphIndex < glyphs.length; glyphIndex++) { + int n = 2 * glyphIndex; + if (ai.gposAdjustments[glyphIndex] != null) { + for (int p = 0; p < 4; p++) { + positions[n + p] += ai.gposAdjustments[glyphIndex][p] / 1000f; + } + } + positions[n + 2] += positions[n] + getGlyphWidth(glyphIndex); + } + } else { + for (int i = 0, n = 2; i < glyphs.length; i++, n += 2) { + int kern = i < glyphs.length - 1 && letterSpaceAdjustments[i + 1] != null + ? letterSpaceAdjustments[i + 1].getOpt() + : 0; + positions[n] = positions[n - 2] + getGlyphWidth(i) + kern / 1000f; + positions[n + 1] = 0; + } + } + } + + private float getGlyphWidth(int index) { + return fontMetrics.getWidth(glyphs[index], fontSize) / 1000000f; + } + + public GVTFont getFont() { + return font; + } + + public FontRenderContext getFontRenderContext() { + return frc; + } + + public int getGlyphCode(int glyphIndex) { + return glyphs[glyphIndex]; + } + + public int[] getGlyphCodes(int beginGlyphIndex, int numEntries, + int[] codeReturn) { + if (codeReturn == null) { + codeReturn = new int[numEntries]; + } + System.arraycopy(glyphs, beginGlyphIndex, codeReturn, 0, numEntries); + return codeReturn; + } + + public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException(); + } + + public Shape getGlyphLogicalBounds(int glyphIndex) { + GVTGlyphMetrics metrics = getGlyphMetrics(glyphIndex); + Point2D pos = getGlyphPosition(glyphIndex); + GVTLineMetrics fontMetrics = font.getLineMetrics(0); + Rectangle2D bounds = new Rectangle2D.Float(0, -fontMetrics.getDescent(), metrics.getHorizontalAdvance(), + fontMetrics.getAscent() + fontMetrics.getDescent()); + AffineTransform t = AffineTransform.getTranslateInstance(pos.getX(), pos.getY()); + AffineTransform transf = getGlyphTransform(glyphIndex); + if (transf != null) { + t.concatenate(transf); + } + t.scale(1, -1); // Translate from glyph coordinate system to user + return t.createTransformedShape(bounds); + } + + public GVTGlyphMetrics getGlyphMetrics(int glyphIndex) { + Rectangle2D bbox = getBoundingBoxes()[glyphIndex]; + return new GVTGlyphMetrics(positions[2 * (glyphIndex + 1)] - positions[2 * glyphIndex], + (fontMetrics.getAscender(fontSize) - fontMetrics.getDescender(fontSize)) / 1000000f, + bbox, GlyphMetrics.STANDARD); + } + + public Shape getGlyphOutline(int glyphIndex) { + Shape glyphBox = getBoundingBoxes()[glyphIndex]; + AffineTransform tr = AffineTransform.getTranslateInstance(positions[glyphIndex * 2], + positions[glyphIndex * 2 + 1]); + AffineTransform glyphTransform = getGlyphTransform(glyphIndex); + if (glyphTransform != null) { + tr.concatenate(glyphTransform); + } + return tr.createTransformedShape(glyphBox); + } + + public Rectangle2D getGlyphCellBounds(int glyphIndex) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException(); + } + + public Point2D getGlyphPosition(int glyphIndex) { + int positionIndex = glyphIndex * 2; + return new Point2D.Float(positions[positionIndex], positions[positionIndex + 1]); + } + + public float[] getGlyphPositions(int beginGlyphIndex, int numEntries, float[] positionReturn) { + if (positionReturn == null) { + positionReturn = new float[numEntries * 2]; + } + System.arraycopy(positions, beginGlyphIndex * 2, positionReturn, 0, numEntries * 2); + return positionReturn; + } + + public AffineTransform getGlyphTransform(int glyphIndex) { + return glyphTransforms[glyphIndex]; + } + + public Shape getGlyphVisualBounds(int glyphIndex) { + Rectangle2D bbox = getBoundingBoxes()[glyphIndex]; + Point2D pos = getGlyphPosition(glyphIndex); + AffineTransform t = AffineTransform.getTranslateInstance(pos.getX(), pos.getY()); + AffineTransform transf = getGlyphTransform(glyphIndex); + if (transf != null) { + t.concatenate(transf); + } + return t.createTransformedShape(bbox); + } + + public Rectangle2D getLogicalBounds() { + if (logicalBounds == null) { + GeneralPath logicalBoundsPath = new GeneralPath(); + for (int i = 0; i < getNumGlyphs(); i++) { + Shape glyphLogicalBounds = getGlyphLogicalBounds(i); + logicalBoundsPath.append(glyphLogicalBounds, false); + } + logicalBounds = logicalBoundsPath.getBounds2D(); + } + return logicalBounds; + } + + public int getNumGlyphs() { + return glyphs.length; + } + + public Shape getOutline() { + if (outline == null) { + outline = new GeneralPath(); + for (int i = 0; i < glyphs.length; i++) { + outline.append(getGlyphOutline(i), false); + } + } + return outline; + } + + public Shape getOutline(float x, float y) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException(); + } + + public Rectangle2D getGeometricBounds() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException(); + } + + public Rectangle2D getBounds2D(AttributedCharacterIterator aci) { + return getOutline().getBounds2D(); + } + + public void setGlyphPosition(int glyphIndex, Point2D newPos) { + int idx = glyphIndex * 2; + positions[idx] = (float) newPos.getX(); + positions[idx + 1] = (float) newPos.getY(); + } + + public void setGlyphTransform(int glyphIndex, AffineTransform newTX) { + glyphTransforms[glyphIndex] = newTX; + } + + public void setGlyphVisible(int glyphIndex, boolean visible) { + glyphVisibilities[glyphIndex] = visible; + } + + public boolean isGlyphVisible(int glyphIndex) { + return glyphVisibilities[glyphIndex]; + } + + public int getCharacterCount(int startGlyphIndex, int endGlyphIndex) { + // TODO Not that simple if complex scripts are involved + return endGlyphIndex - startGlyphIndex + 1; + } + + public void draw(Graphics2D graphics2d, AttributedCharacterIterator aci) { + // NOP + } + + private Rectangle2D[] getBoundingBoxes() { + if (boundingBoxes == null) { + buildBoundingBoxes(); + } + return boundingBoxes; + } + + private void buildBoundingBoxes() { + boundingBoxes = new Rectangle2D[glyphs.length]; + for (int i = 0; i < glyphs.length; i++) { + Rectangle bbox = fontMetrics.getBoundingBox(glyphs[i], fontSize); + boundingBoxes[i] = new Rectangle2D.Float(bbox.x / 1000000f, -(bbox.y + bbox.height) / 1000000f, + bbox.width / 1000000f, bbox.height / 1000000f); + } + } + +} diff --git a/src/java/org/apache/fop/svg/font/FilteringFontFamilyResolver.java b/src/java/org/apache/fop/svg/font/FilteringFontFamilyResolver.java new file mode 100644 index 000000000..93b92ea36 --- /dev/null +++ b/src/java/org/apache/fop/svg/font/FilteringFontFamilyResolver.java @@ -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.svg.font; + +import java.io.InputStream; + +import org.apache.batik.bridge.FontFace; +import org.apache.batik.gvt.font.GVTFontFamily; + + +public class FilteringFontFamilyResolver implements FOPFontFamilyResolver { + + private final FOPFontFamilyResolver delegate; + + public FilteringFontFamilyResolver(FOPFontFamilyResolver delegate) { + this.delegate = delegate; + } + + public FOPGVTFontFamily resolve(String familyName) { + return delegate.resolve(familyName); + } + + public GVTFontFamily resolve(String familyName, FontFace fontFace) { + return delegate.resolve(familyName, fontFace); + } + + public GVTFontFamily loadFont(InputStream in, FontFace fontFace) throws Exception { + return delegate.loadFont(in, fontFace); + } + + public FOPGVTFontFamily getDefault() { + return delegate.getDefault(); + } + + public FOPGVTFontFamily getFamilyThatCanDisplay(char c) { + return delegate.getFamilyThatCanDisplay(c); + } + +} diff --git a/test/java/org/apache/fop/AbstractBasicTranscoderTest.java b/test/java/org/apache/fop/AbstractBasicTranscoderTest.java index 2087c8df2..7a40b353a 100644 --- a/test/java/org/apache/fop/AbstractBasicTranscoderTest.java +++ b/test/java/org/apache/fop/AbstractBasicTranscoderTest.java @@ -24,13 +24,15 @@ import java.io.InputStream; import org.junit.Test; +import static org.junit.Assert.assertTrue; + +import org.apache.commons.io.output.ByteArrayOutputStream; + import org.apache.batik.transcoder.Transcoder; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; -import org.apache.commons.io.output.ByteArrayOutputStream; import static org.apache.fop.FOPTestUtils.getBaseDir; -import static org.junit.Assert.assertTrue; /** * Basic runtime test for FOP's transcoders. It is used to verify that diff --git a/test/java/org/apache/fop/BasicDriverTestCase.java b/test/java/org/apache/fop/BasicDriverTestCase.java index f149b451e..e89a1c558 100644 --- a/test/java/org/apache/fop/BasicDriverTestCase.java +++ b/test/java/org/apache/fop/BasicDriverTestCase.java @@ -28,11 +28,13 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; -import org.apache.fop.apps.FOPException; import org.junit.Test; +import static org.junit.Assert.assertTrue; + import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; @@ -40,7 +42,6 @@ import org.apache.fop.apps.MimeConstants; import org.apache.fop.cli.InputHandler; import static org.apache.fop.FOPTestUtils.getBaseDir; -import static org.junit.Assert.assertTrue; /** * Basic runtime test for the old Fop class. It is used to verify that @@ -136,7 +137,7 @@ public class BasicDriverTestCase { InputHandler handler = new InputHandler(xmlFile, xsltFile, null); try { handler.renderTo(foUserAgent, MimeConstants.MIME_PDF, baout); - } catch (FOPException e) {} + } catch (FOPException e) { /* NOP */ } } } diff --git a/test/java/org/apache/fop/BasicDriverTestSuite.java b/test/java/org/apache/fop/BasicDriverTestSuite.java index 8330a5f7f..68619926a 100644 --- a/test/java/org/apache/fop/BasicDriverTestSuite.java +++ b/test/java/org/apache/fop/BasicDriverTestSuite.java @@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses; * Test suite for basic functionality of FOP's Driver API. */ @RunWith(Suite.class) -@SuiteClasses({ BasicDriverTestCase.class }) +@SuiteClasses(BasicDriverTestCase.class) public class BasicDriverTestSuite { } diff --git a/test/java/org/apache/fop/BasicPSTranscoderTestCase.java b/test/java/org/apache/fop/BasicPSTranscoderTestCase.java index f2f233a5a..2d6fc0d81 100644 --- a/test/java/org/apache/fop/BasicPSTranscoderTestCase.java +++ b/test/java/org/apache/fop/BasicPSTranscoderTestCase.java @@ -20,6 +20,7 @@ package org.apache.fop; import org.apache.batik.transcoder.Transcoder; + import org.apache.fop.render.ps.PSTranscoder; /** diff --git a/test/java/org/apache/fop/DebugHelper.java b/test/java/org/apache/fop/DebugHelper.java index 6705d2f56..9ee7de072 100644 --- a/test/java/org/apache/fop/DebugHelper.java +++ b/test/java/org/apache/fop/DebugHelper.java @@ -25,7 +25,10 @@ import org.apache.fop.logging.LoggingElementListObserver; /** * Handles some standard tasks for debugging. */ -public class DebugHelper { +public final class DebugHelper { + + private DebugHelper() { + } private static boolean elObserversRegistered = false; diff --git a/test/java/org/apache/fop/DigestFilterTestCase.java b/test/java/org/apache/fop/DigestFilterTestCase.java index 5606c2b66..679b65aee 100644 --- a/test/java/org/apache/fop/DigestFilterTestCase.java +++ b/test/java/org/apache/fop/DigestFilterTestCase.java @@ -19,8 +19,6 @@ package org.apache.fop; -import static org.junit.Assert.assertTrue; - import java.io.IOException; import java.io.StringReader; import java.security.NoSuchAlgorithmException; @@ -28,13 +26,16 @@ import java.security.NoSuchAlgorithmException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; -import org.apache.fop.util.DigestFilter; import org.junit.Before; import org.junit.Test; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; +import static org.junit.Assert.assertTrue; + +import org.apache.fop.util.DigestFilter; + /** * Test case for digesting SAX filter. * diff --git a/test/java/org/apache/fop/KnuthAlgorithmTestCase.java b/test/java/org/apache/fop/KnuthAlgorithmTestCase.java index b5132fee9..aa92191de 100644 --- a/test/java/org/apache/fop/KnuthAlgorithmTestCase.java +++ b/test/java/org/apache/fop/KnuthAlgorithmTestCase.java @@ -23,6 +23,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; + import static org.junit.Assert.assertEquals; import org.apache.fop.layoutmgr.BlockKnuthSequence; diff --git a/test/java/org/apache/fop/URIResolutionTestCase.java b/test/java/org/apache/fop/URIResolutionTestCase.java index e1015306e..e01271f2b 100644 --- a/test/java/org/apache/fop/URIResolutionTestCase.java +++ b/test/java/org/apache/fop/URIResolutionTestCase.java @@ -41,6 +41,9 @@ import org.junit.BeforeClass; import org.junit.Test; import org.w3c.dom.Document; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.xpath.XPathAPI; @@ -59,8 +62,6 @@ import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.render.xml.XMLRenderer; import static org.apache.fop.FOPTestUtils.getBaseDir; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; /** * Tests URI resolution facilities. diff --git a/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java b/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java index fc5f1825c..e9134a90b 100644 --- a/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java +++ b/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java @@ -19,11 +19,11 @@ package org.apache.fop.afp; -import static org.junit.Assert.assertEquals; - import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; + /** * Test case for {@link AFPObjectAreaInfo}. */ diff --git a/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java b/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java index 47c93064c..e9806f944 100644 --- a/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java +++ b/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java @@ -19,11 +19,11 @@ package org.apache.fop.afp; -import static org.junit.Assert.assertEquals; - import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; + /** * Test case for {@link AFPPaintingState}. */ diff --git a/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java b/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java index 21540221f..9d805a7da 100644 --- a/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java +++ b/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java @@ -26,13 +26,13 @@ import java.io.IOException; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import org.apache.xmlgraphics.util.MimeConstants; import org.apache.fop.apps.io.ResourceResolverFactory; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - /** * Test case for {@link AFPResourceManager}. */ diff --git a/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java b/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java index a7cf57ebe..178e5c6ad 100644 --- a/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java +++ b/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java @@ -19,8 +19,6 @@ package org.apache.fop.afp; -import static org.junit.Assert.assertTrue; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -29,11 +27,11 @@ import java.util.Arrays; import org.junit.Test; +import static org.junit.Assert.assertTrue; + import org.apache.commons.io.IOUtils; -import org.apache.fop.afp.util.AFPResourceUtil; -import org.junit.Test; -import static org.junit.Assert.assertTrue; +import org.apache.fop.afp.util.AFPResourceUtil; /** * Tests the {@link AFPResourceUtil} class. @@ -133,7 +131,7 @@ public class AFPResourceUtilTestCase { * names fails. * @throws Exception - */ - @Test(expected=Exception.class) + @Test(expected = Exception.class) public void testResourceNameMismatch() throws Exception { testResource(RESOURCE_NAME_MISMATCH, PSEG_B); } @@ -156,6 +154,6 @@ public class AFPResourceUtilTestCase { } private interface ResourceCopier { - public void copy(InputStream in, OutputStream out) throws IOException; + void copy(InputStream in, OutputStream out) throws IOException; } } diff --git a/test/java/org/apache/fop/afp/fonts/IntegerKeyStoreTestCase.java b/test/java/org/apache/fop/afp/fonts/IntegerKeyStoreTestCase.java new file mode 100644 index 000000000..96c0618a7 --- /dev/null +++ b/test/java/org/apache/fop/afp/fonts/IntegerKeyStoreTestCase.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp.fonts; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +public class IntegerKeyStoreTestCase { + + @Test + public void getAndPut() { + IntegerKeyStore<Integer> sut = new IntegerKeyStore<Integer>(); + assertNull(sut.get(0)); + sut.put(0, 0); + assertEquals(Integer.valueOf(0), sut.get(0)); + sut.put(0, 1); + assertEquals(Integer.valueOf(1), sut.get(0)); + sut.put(0, null); + assertNull(sut.get(0)); + try { + sut.put(-1, 0); + fail("Negative index"); + } catch (IndexOutOfBoundsException e) { + // As expected + } + } + +} diff --git a/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java b/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java index b77ef6e12..17c47743c 100644 --- a/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java +++ b/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java @@ -16,16 +16,17 @@ */ package org.apache.fop.afp.goca; -import static org.junit.Assert.assertEquals; - import java.io.ByteArrayOutputStream; import java.io.IOException; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + import org.apache.fop.afp.fonts.CharacterSet; import org.apache.fop.afp.fonts.CharacterSetBuilder; import org.apache.fop.fonts.Typeface; -import org.junit.Before; -import org.junit.Test; public class GraphicsCharacterStringTestCase { private GraphicsCharacterString gcsCp500; diff --git a/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java index 65c0224c2..a4c80cc65 100644 --- a/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java +++ b/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java @@ -19,10 +19,6 @@ package org.apache.fop.afp.modca; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -30,9 +26,14 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.apache.fop.afp.Streamable; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.apache.fop.afp.Streamable; + /** * Tests the {@link AbstractAFPObject} class. */ diff --git a/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java index 5c863b6e4..0593ae637 100644 --- a/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java +++ b/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java @@ -19,12 +19,12 @@ package org.apache.fop.afp.modca; -import static org.junit.Assert.assertTrue; - import java.util.Arrays; import org.junit.Test; +import static org.junit.Assert.assertTrue; + /** * Tests the {@linkplain AbstractAFPObject} class. */ diff --git a/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java index faef0a4f6..d0a543087 100644 --- a/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java +++ b/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java @@ -21,7 +21,8 @@ package org.apache.fop.afp.modca; import java.io.IOException; -public abstract class AbstractStructuredObjectTest<S extends AbstractStructuredObject> extends AbstractAFPObjectTest<S> { +public abstract class AbstractStructuredObjectTest<S extends AbstractStructuredObject> + extends AbstractAFPObjectTest<S> { /** * Test writeStart() - test that the contract is maintained with diff --git a/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java index 10c154550..fe25996bb 100644 --- a/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java +++ b/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java @@ -19,10 +19,6 @@ package org.apache.fop.afp.modca; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -33,6 +29,10 @@ import java.util.List; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import org.apache.fop.afp.modca.triplets.AbstractTriplet; import org.apache.fop.afp.modca.triplets.AttributeQualifierTriplet; import org.apache.fop.afp.modca.triplets.CommentTriplet; diff --git a/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java b/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java index 0449f2599..7e096f98b 100644 --- a/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java +++ b/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java @@ -19,16 +19,17 @@ package org.apache.fop.afp.modca; -import static org.junit.Assert.assertTrue; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; -import org.apache.fop.afp.util.BinaryUtils; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertTrue; + +import org.apache.fop.afp.util.BinaryUtils; + /** * Test {@link IncludeObject} */ diff --git a/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java b/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java index c80ef086c..176344618 100644 --- a/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java +++ b/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java @@ -19,11 +19,6 @@ package org.apache.fop.afp.parser; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.EOFException; @@ -32,6 +27,11 @@ import java.util.Arrays; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * MODCAParser and MODCAParser.UnparsedStructuredField Unit tests */ diff --git a/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java b/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java index 338c5e6f4..8d6c79d05 100644 --- a/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java +++ b/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java @@ -24,15 +24,16 @@ import java.io.OutputStream; import org.junit.Test; -import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars; -import org.apache.fop.afp.ptoca.TransparentDataControlSequence.TransparentData; - -import static org.apache.fop.afp.ptoca.PtocaConstants.TRANSPARENT_DATA_MAX_SIZE; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars; +import org.apache.fop.afp.ptoca.TransparentDataControlSequence.TransparentData; + +import static org.apache.fop.afp.ptoca.PtocaConstants.TRANSPARENT_DATA_MAX_SIZE; + public class TransparentDataControlSequenceTestCase { private EncodedChars encodedChars; diff --git a/test/java/org/apache/fop/apps/AbstractRendererConfigParserTester.java b/test/java/org/apache/fop/apps/AbstractRendererConfigParserTester.java index 9739db2f3..e4c9ceb44 100644 --- a/test/java/org/apache/fop/apps/AbstractRendererConfigParserTester.java +++ b/test/java/org/apache/fop/apps/AbstractRendererConfigParserTester.java @@ -19,6 +19,9 @@ package org.apache.fop.apps; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; @@ -28,9 +31,6 @@ import org.apache.fop.fonts.FontManager; import org.apache.fop.render.RendererConfig; import org.apache.fop.render.RendererConfig.RendererConfigParser; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - public abstract class AbstractRendererConfigParserTester<B extends RendererConfBuilder, C extends RendererConfig> { diff --git a/test/java/org/apache/fop/apps/AbstractRendererConfiguratorTest.java b/test/java/org/apache/fop/apps/AbstractRendererConfiguratorTest.java index 58c14f5df..2487c0a63 100644 --- a/test/java/org/apache/fop/apps/AbstractRendererConfiguratorTest.java +++ b/test/java/org/apache/fop/apps/AbstractRendererConfiguratorTest.java @@ -24,16 +24,17 @@ import java.io.IOException; import org.xml.sax.SAXException; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.fop.apps.FopConfBuilder.RendererConfBuilder; import org.apache.fop.render.PrintRendererConfigurator; import org.apache.fop.render.intermediate.IFDocumentHandler; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public abstract class AbstractRendererConfiguratorTest<T extends PrintRendererConfigurator, B extends RendererConfBuilder> { +public abstract class AbstractRendererConfiguratorTest<T extends PrintRendererConfigurator, + B extends RendererConfBuilder> { protected final String mimeType; protected FOUserAgent userAgent; diff --git a/test/java/org/apache/fop/apps/EnvironmentalProfileFactoryTestCase.java b/test/java/org/apache/fop/apps/EnvironmentalProfileFactoryTestCase.java index e94403e71..83bfd2076 100644 --- a/test/java/org/apache/fop/apps/EnvironmentalProfileFactoryTestCase.java +++ b/test/java/org/apache/fop/apps/EnvironmentalProfileFactoryTestCase.java @@ -21,7 +21,6 @@ import java.net.URI; import org.junit.Test; - import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; diff --git a/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java b/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java index e504c4bc4..86b4e7c04 100644 --- a/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java +++ b/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java @@ -27,6 +27,12 @@ import java.util.List; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.area.AreaTreeHandler; import org.apache.fop.area.Block; @@ -45,12 +51,6 @@ import org.apache.fop.layoutmgr.PageSequenceLayoutManager; import org.apache.fop.layoutmgr.StaticContentLayoutManager; import org.apache.fop.layoutmgr.inline.ContentLayoutManager; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - /** * Test case for {@link FopFactoryBuilder}. */ diff --git a/test/java/org/apache/fop/apps/FopFactoryTestCase.java b/test/java/org/apache/fop/apps/FopFactoryTestCase.java index 8ac21c994..439ffa44e 100644 --- a/test/java/org/apache/fop/apps/FopFactoryTestCase.java +++ b/test/java/org/apache/fop/apps/FopFactoryTestCase.java @@ -24,16 +24,15 @@ import java.io.IOException; import org.junit.Test; import org.xml.sax.SAXException; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.config.BaseConstructiveUserConfigTest; -import org.apache.fop.render.RendererConfig.RendererConfigParser; -import org.apache.fop.render.pdf.PDFRendererConfig; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.apache.fop.config.BaseConstructiveUserConfigTest; +import org.apache.fop.render.RendererConfig.RendererConfigParser; +import org.apache.fop.render.pdf.PDFRendererConfig; + public class FopFactoryTestCase extends BaseConstructiveUserConfigTest { public FopFactoryTestCase() throws SAXException, IOException { diff --git a/test/java/org/apache/fop/apps/PDFRendererConfBuilder.java b/test/java/org/apache/fop/apps/PDFRendererConfBuilder.java index 13ca3df6b..3da4e1daf 100644 --- a/test/java/org/apache/fop/apps/PDFRendererConfBuilder.java +++ b/test/java/org/apache/fop/apps/PDFRendererConfBuilder.java @@ -22,10 +22,8 @@ package org.apache.fop.apps; import org.w3c.dom.Element; import org.apache.fop.apps.FopConfBuilder.RendererConfBuilder; -import org.apache.fop.pdf.PDFEncryptionParams; import org.apache.fop.render.RendererConfigOption; import org.apache.fop.render.pdf.PDFEncryptionOption; -import org.apache.fop.render.pdf.PDFRendererOption; import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_LENGTH; import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_PARAMS; diff --git a/test/java/org/apache/fop/apps/io/BaseURIResolutionTest.java b/test/java/org/apache/fop/apps/io/BaseURIResolutionTest.java index 2131407c1..e04283718 100644 --- a/test/java/org/apache/fop/apps/io/BaseURIResolutionTest.java +++ b/test/java/org/apache/fop/apps/io/BaseURIResolutionTest.java @@ -34,6 +34,8 @@ import javax.xml.transform.stream.StreamSource; import org.xml.sax.SAXException; +import static org.junit.Assert.assertTrue; + import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; @@ -48,7 +50,6 @@ import org.apache.fop.apps.FopFactoryBuilder; import org.apache.fop.apps.MimeConstants; import static org.apache.fop.FOPTestUtils.getBaseDir; -import static org.junit.Assert.assertTrue; public abstract class BaseURIResolutionTest { diff --git a/test/java/org/apache/fop/apps/io/FontURIResolver.java b/test/java/org/apache/fop/apps/io/FontURIResolver.java index 40d6c7402..781aca368 100644 --- a/test/java/org/apache/fop/apps/io/FontURIResolver.java +++ b/test/java/org/apache/fop/apps/io/FontURIResolver.java @@ -33,14 +33,13 @@ import javax.xml.transform.TransformerException; import org.junit.Test; import org.xml.sax.SAXException; -import org.apache.fop.apps.FopConfBuilder; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.apps.PDFRendererConfBuilder; - import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.io.Resource; +import org.apache.fop.apps.FopConfBuilder; +import org.apache.fop.apps.PDFRendererConfBuilder; + public class FontURIResolver extends BaseURIResolutionTest { public enum Event { diff --git a/test/java/org/apache/fop/area/ViewportTest.java b/test/java/org/apache/fop/area/ViewportTest.java index cb2282071..46412c83d 100644 --- a/test/java/org/apache/fop/area/ViewportTest.java +++ b/test/java/org/apache/fop/area/ViewportTest.java @@ -19,13 +19,13 @@ package org.apache.fop.area; +import java.awt.Rectangle; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import java.awt.Rectangle; - /** * Tests implementations of the {@linkplain Viewport} interface. */ diff --git a/test/java/org/apache/fop/area/ViewportTestSuite.java b/test/java/org/apache/fop/area/ViewportTestSuite.java index 065e07bf9..891f1d081 100644 --- a/test/java/org/apache/fop/area/ViewportTestSuite.java +++ b/test/java/org/apache/fop/area/ViewportTestSuite.java @@ -19,11 +19,12 @@ package org.apache.fop.area; -import org.apache.fop.area.inline.InlineViewportTestCase; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; +import org.apache.fop.area.inline.InlineViewportTestCase; + /** * A suite of all the tests relating to the {@linkplain Viewport} interface. */ diff --git a/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java b/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java index edcf99d14..cba5759cf 100644 --- a/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java +++ b/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java @@ -19,9 +19,10 @@ package org.apache.fop.area.inline; -import org.apache.fop.area.ViewportTest; import org.junit.Test; +import org.apache.fop.area.ViewportTest; + /** * Tests the {@linkplain InlineViewport} class. */ diff --git a/test/java/org/apache/fop/check/ChecksFactory.java b/test/java/org/apache/fop/check/ChecksFactory.java index a493c09f2..d77ce422d 100644 --- a/test/java/org/apache/fop/check/ChecksFactory.java +++ b/test/java/org/apache/fop/check/ChecksFactory.java @@ -37,7 +37,7 @@ public abstract class ChecksFactory<C extends Check> { /** * A factory to create a particular kind of check. */ - protected static interface CheckFactory<C> { + protected interface CheckFactory<C> { /** * Creates a {@link Check} instance from the given XML element. diff --git a/test/java/org/apache/fop/cli/CommandLineOptionsTestCase.java b/test/java/org/apache/fop/cli/CommandLineOptionsTestCase.java index 9a80fd964..1be3daa84 100644 --- a/test/java/org/apache/fop/cli/CommandLineOptionsTestCase.java +++ b/test/java/org/apache/fop/cli/CommandLineOptionsTestCase.java @@ -19,15 +19,16 @@ package org.apache.fop.cli; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.io.IOException; -import org.apache.fop.apps.FOPException; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.apache.fop.apps.FOPException; + public class CommandLineOptionsTestCase { private final CommandLineOptions clo = new CommandLineOptions(); diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java b/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java index f20e113c1..8ed1af217 100644 --- a/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java @@ -19,26 +19,23 @@ package org.apache.fop.complexscripts.bidi; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.fop.complexscripts.bidi.UnicodeBidiAlgorithm; - import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + /** * <p>Test case for Unicode Bidi Algorithm.</p> - * @author Glenn Adams */ public class BidiAlgorithmTestCase { /** * logging instance */ - private static final Log log = LogFactory.getLog(BidiAlgorithmTestCase.class); // CSOK: ConstantNameCheck + private static final Log log = LogFactory.getLog(BidiAlgorithmTestCase.class); /** * Concatenated array of <test-set,test-sequence> tuples @@ -122,7 +119,7 @@ public class BidiAlgorithmTestCase { } if (includeSequence(testSet, testSequence)) { includedSequences++; - if (! excludeSequence(testSet, testSequence)) { + if (!excludeSequence(testSet, testSequence)) { if (testBidiAlgorithm(testSet, testSequence, la, ra, ta, bs)) { passedSequences++; } @@ -151,7 +148,7 @@ public class BidiAlgorithmTestCase { } private boolean includeSequence(int testSet, int testSequence) { - if (! includeTestSet(testSet)) { + if (!includeTestSet(testSet)) { return false; } else { for (int i = 0, n = INCLUSIONS.length / 2; i < n; i++) { @@ -196,7 +193,8 @@ public class BidiAlgorithmTestCase { return false; } - private boolean testBidiAlgorithm(int testSet, int testSequence, int[] la, int[] ra, int[] ta, int bs) throws Exception { + private boolean testBidiAlgorithm(int testSet, int testSequence, int[] la, int[] ra, int[] ta, int bs) + throws Exception { boolean passed = true; int n = la.length; if (ra.length != n) { @@ -211,14 +209,14 @@ public class BidiAlgorithmTestCase { // LTR if ((bs & 2) != 0) { int[] levels = UnicodeBidiAlgorithm.resolveLevels(null, ta, 0, new int [ n ], true); - if (! verifyResults(la, levels, ta, 0, testSet, testSequence)) { + if (!verifyResults(la, levels, ta, 0, testSet, testSequence)) { passed = false; } } // RTL if ((bs & 4) != 0) { int[] levels = UnicodeBidiAlgorithm.resolveLevels(null, ta, 1, new int [ n ], true); - if (! verifyResults(la, levels, ta, 1, testSet, testSequence)) { + if (!verifyResults(la, levels, ta, 1, testSet, testSequence)) { passed = false; } } diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java b/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java index 10a84b856..f393e5b70 100644 --- a/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java @@ -19,14 +19,13 @@ package org.apache.fop.complexscripts.bidi; -import org.apache.fop.complexscripts.bidi.BidiClass; -import org.apache.fop.util.CharUtilities; - import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import org.apache.fop.util.CharUtilities; + public class BidiClassTestCase { @Test @@ -46,8 +45,8 @@ public class BidiClassTestCase { private void testBidiClass(int[] da) throws Exception { int bc = da[0]; for (int i = 1, n = da.length; i < n; i += 2) { - int s = da[i+0]; - int e = da[i+1]; + int s = da[i + 0]; + int e = da[i + 1]; for (int c = s; c < e; c++) { int cbc = BidiClass.getBidiClass(c); assertEquals("bad bidi class for CH(" + CharUtilities.format(c) + ")", bc, cbc); diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java index 6be0c1fa9..49a5c9455 100644 --- a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java @@ -65,7 +65,7 @@ public final class BidiTestData { data = null; } finally { if (is != null) { - try { is.close(); } catch (Exception e) {} + try { is.close(); } catch (Exception e) { /* NOP */ } } } return data; diff --git a/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java index af929d3a1..f1512903c 100644 --- a/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java +++ b/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java @@ -21,21 +21,14 @@ package org.apache.fop.complexscripts.fonts; import java.io.File; -import org.apache.fop.complexscripts.fonts.GlyphSubtable; -import org.apache.fop.complexscripts.fonts.GlyphDefinitionSubtable; -import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable; -import org.apache.fop.complexscripts.fonts.GlyphTable.LookupSpec; -import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable; -import org.apache.fop.complexscripts.fonts.ttx.TTXFile; -import org.apache.fop.complexscripts.util.GlyphContextTester; -import org.apache.fop.complexscripts.util.GlyphSequence; - import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.apache.fop.complexscripts.fonts.ttx.TTXFile; + public class GDEFTestCase { private static String ttxFilesRoot = "test/resources/complexscripts"; diff --git a/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java index 270b56797..cf63b4eff 100644 --- a/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java +++ b/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java @@ -20,18 +20,6 @@ package org.apache.fop.complexscripts.fonts; import java.io.File; -import java.util.List; -import java.util.Map; - -import org.apache.fop.complexscripts.fonts.GlyphSubtable; -import org.apache.fop.complexscripts.fonts.GlyphPositioningSubtable; -import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; -import org.apache.fop.complexscripts.fonts.GlyphTable.LookupSpec; -import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable; -import org.apache.fop.complexscripts.fonts.ttx.TTXFile; -import org.apache.fop.complexscripts.util.GlyphContextTester; -import org.apache.fop.complexscripts.util.GlyphSequence; -import org.apache.fop.complexscripts.util.ScriptContextTester; import org.junit.Test; @@ -40,6 +28,14 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable; +import org.apache.fop.complexscripts.fonts.ttx.TTXFile; +import org.apache.fop.complexscripts.util.GlyphContextTester; +import org.apache.fop.complexscripts.util.GlyphSequence; +import org.apache.fop.complexscripts.util.ScriptContextTester; + +// CSOFF: LineLength + public class GPOSTestCase implements ScriptContextTester, GlyphContextTester { private static String ttxFilesRoot = "test/resources/complexscripts"; diff --git a/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java index b235fa58c..3f23d9ab3 100644 --- a/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java +++ b/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java @@ -21,18 +21,6 @@ package org.apache.fop.complexscripts.fonts; import java.io.File; import java.nio.IntBuffer; -import java.util.List; -import java.util.Map; - -import org.apache.fop.complexscripts.fonts.GlyphSubtable; -import org.apache.fop.complexscripts.fonts.GlyphSubstitutionSubtable; -import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable; -import org.apache.fop.complexscripts.fonts.GlyphTable.LookupSpec; -import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable; -import org.apache.fop.complexscripts.fonts.ttx.TTXFile; -import org.apache.fop.complexscripts.util.GlyphContextTester; -import org.apache.fop.complexscripts.util.GlyphSequence; -import org.apache.fop.complexscripts.util.ScriptContextTester; import org.junit.Test; @@ -41,6 +29,14 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable; +import org.apache.fop.complexscripts.fonts.ttx.TTXFile; +import org.apache.fop.complexscripts.util.GlyphContextTester; +import org.apache.fop.complexscripts.util.GlyphSequence; +import org.apache.fop.complexscripts.util.ScriptContextTester; + +// CSOFF: LineLength + public class GSUBTestCase implements ScriptContextTester, GlyphContextTester { private static String ttxFilesRoot = "test/resources/complexscripts"; diff --git a/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java b/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java index c106e65c8..178203ff6 100644 --- a/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java +++ b/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java @@ -21,11 +21,9 @@ package org.apache.fop.complexscripts.fonts.ttx; import java.io.File; import java.io.IOException; - import java.nio.IntBuffer; - -import java.util.Arrays; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; @@ -41,21 +39,23 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fop.complexscripts.fonts.GlyphClassTable; import org.apache.fop.complexscripts.fonts.GlyphCoverageTable; -import org.apache.fop.complexscripts.fonts.GlyphDefinitionSubtable; import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable; import org.apache.fop.complexscripts.fonts.GlyphMappingTable; -import org.apache.fop.complexscripts.fonts.GlyphPositioningSubtable; import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.Anchor; import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.MarkAnchor; import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.PairValues; import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.Value; -import org.apache.fop.complexscripts.fonts.GlyphSubstitutionSubtable; import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable; import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable.Ligature; import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable.LigatureSet; @@ -66,11 +66,6 @@ import org.apache.fop.complexscripts.util.GlyphSequence; import org.apache.fop.complexscripts.util.UTF32; import org.apache.fop.util.CharUtilities; -import org.xml.sax.Attributes; -import org.xml.sax.Locator; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - // CSOFF: LineLengthCheck @@ -87,8 +82,6 @@ import org.xml.sax.helpers.DefaultHandler; * files directly in the FOP distribution. In such cases, <code>TTX</code> files are used * to distribute a subset of the complex script advanced table information contained in * certain font files to facilitate testing. - * - * @author Glenn Adams */ public class TTXFile { @@ -100,22 +93,22 @@ public class TTXFile { private static final String DEFAULT_LANGUAGE_TAG = "dflt"; /** ttxfile cache */ - private static Map<String,TTXFile> cache = new HashMap<String,TTXFile>(); + private static Map<String, TTXFile> cache = new HashMap<String, TTXFile>(); // transient parsing state private Locator locator; // current document locator private Stack<String[]> elements; // stack of ttx elements being parsed - private Map<String,Integer> glyphIds; // map of glyph names to glyph identifiers + private Map<String, Integer> glyphIds; // map of glyph names to glyph identifiers private List<int[]> cmapEntries; // list of <charCode,glyphCode> pairs private Vector<int[]> hmtxEntries; // vector of <width,lsb> pairs - private Map<String,Integer> glyphClasses; // map of glyph names to glyph classes - private Map<String,Map<String,List<String>>> scripts; // map of script tag to Map<language-tag,List<features-id>>> - private Map<String,List<String>> languages; // map of language tag to List<feature-id> - private Map<String,Object[]> features; // map of feature id to Object[2] : { feature-tag, List<lookup-id> } + private Map<String, Integer> glyphClasses; // map of glyph names to glyph classes + private Map<String, Map<String, List<String>>> scripts; // map of script tag to Map<language-tag,List<features-id>>> + private Map<String, List<String>> languages; // map of language tag to List<feature-id> + private Map<String, Object[]> features; // map of feature id to Object[2] : { feature-tag, List<lookup-id> } private List<String> languageFeatures; // list of language system feature ids, where first is (possibly null) required feature id private List<String> featureLookups; // list of lookup ids for feature being constructed private List<Integer> coverageEntries; // list of entries for coverage table being constructed - private Map<String,GlyphCoverageTable> coverages; // map of coverage table keys to coverage tables + private Map<String, GlyphCoverageTable> coverages; // map of coverage table keys to coverage tables private List subtableEntries; // list of lookup subtable entries private List<GlyphSubtable> subtables; // list of constructed subtables private List<Integer> alternates; // list of alternates in alternate set being constructed @@ -162,8 +155,8 @@ public class TTXFile { // resultant state private int upem; // units per em - private Map<Integer,Integer> cmap; // constructed character map - private Map<Integer,Integer> gmap; // constructed glyph map + private Map<Integer, Integer> cmap; // constructed character map + private Map<Integer, Integer> gmap; // constructed glyph map private int[][] hmtx; // constructed horizontal metrics - array of design { width, lsb } pairs, indexed by glyph code private int[] widths; // pdf normalized widths (millipoints) private GlyphDefinitionTable gdef; // constructed glyph definition table @@ -172,17 +165,17 @@ public class TTXFile { public TTXFile() { elements = new Stack<String[]>(); - glyphIds = new HashMap<String,Integer>(); + glyphIds = new HashMap<String, Integer>(); cmapEntries = new ArrayList<int[]>(); hmtxEntries = new Vector<int[]>(); - glyphClasses = new HashMap<String,Integer>(); - scripts = new HashMap<String,Map<String,List<String>>>(); - languages = new HashMap<String,List<String>>(); - features = new HashMap<String,Object[]>(); + glyphClasses = new HashMap<String, Integer>(); + scripts = new HashMap<String, Map<String, List<String>>>(); + languages = new HashMap<String, List<String>>(); + features = new HashMap<String, Object[]>(); languageFeatures = new ArrayList<String>(); featureLookups = new ArrayList<String>(); coverageEntries = new ArrayList<Integer>(); - coverages = new HashMap<String,GlyphCoverageTable>(); + coverages = new HashMap<String, GlyphCoverageTable>(); subtableEntries = new ArrayList(); subtables = new ArrayList<GlyphSubtable>(); alternates = new ArrayList<Integer>(); @@ -342,7 +335,7 @@ public class TTXFile { long rest1 = tw % upem; long storrest = 1000 * rest1; long ledd2 = (storrest != 0) ? (rest1 / storrest) : 0; - pw = - ((-1000 * tw) / upem - (int) ledd2); + pw = -((-1000 * tw) / upem - (int) ledd2); } else { pw = (tw / upem) * 1000 + ((tw % upem) * 1000) / upem; } @@ -370,7 +363,7 @@ public class TTXFile { public static synchronized void clearCache() { cache.clear(); } - private class Handler extends DefaultHandler { + private final class Handler extends DefaultHandler { private Handler() { } @Override @@ -493,7 +486,7 @@ public class TTXFile { } } else if (en[1].equals("BaseArray")) { String[] pn = new String[] { null, "MarkBasePos" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } } else if (en[1].equals("BaseCoverage")) { @@ -587,7 +580,7 @@ public class TTXFile { if (glyphClass == null) { missingRequiredAttribute(en, "class"); } - if (! glyphIds.containsKey(glyph)) { + if (!glyphIds.containsKey(glyph)) { unsupportedGlyph(en, glyph); } else if (isParent(pn1)) { if (glyphClasses.containsKey(glyph)) { @@ -675,7 +668,7 @@ public class TTXFile { } } else if (en[1].equals("DefaultLangSys")) { String[] pn = new String[] { null, "Script" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } else { assertLanguageFeaturesClear(); @@ -718,7 +711,7 @@ public class TTXFile { } } else if (en[1].equals("Feature")) { String[] pn = new String[] { null, "FeatureRecord" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } else { assertFeatureLookupsClear(); @@ -752,7 +745,7 @@ public class TTXFile { String[] pn1 = new String[] { null, "GSUB" }; String[] pn2 = new String[] { null, "GPOS" }; String[][] pnx = new String[][] { pn1, pn2 }; - if (! isParent(pnx)) { + if (!isParent(pnx)) { notPermittedInElementContext(en, getParent(), pnx); } } else if (en[1].equals("FeatureRecord")) { @@ -885,7 +878,7 @@ public class TTXFile { } } else if (en[1].equals("GlyphOrder")) { String[] pn = new String[] { null, "ttFont" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } } else if (en[1].equals("InputCoverage")) { @@ -923,7 +916,7 @@ public class TTXFile { } } else if (en[1].equals("LangSys")) { String[] pn = new String[] { null, "LangSysRecord" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } else { assertLanguageFeaturesClear(); @@ -953,7 +946,7 @@ public class TTXFile { } } else if (en[1].equals("LigCaretList")) { String[] pn = new String[] { null, "GDEF" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } } else if (en[1].equals("Ligature")) { @@ -991,7 +984,7 @@ public class TTXFile { } } else if (en[1].equals("LigatureArray")) { String[] pn = new String[] { null, "MarkLigPos" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } } else if (en[1].equals("LigatureAttach")) { @@ -1139,7 +1132,7 @@ public class TTXFile { String[] pn1 = new String[] { null, "GSUB" }; String[] pn2 = new String[] { null, "GPOS" }; String[][] pnx = new String[][] { pn1, pn2 }; - if (! isParent(pnx)) { + if (!isParent(pnx)) { notPermittedInElementContext(en, getParent(), pnx); } } else if (en[1].equals("LookupListIndex")) { @@ -1179,7 +1172,7 @@ public class TTXFile { } } else if (en[1].equals("Mark1Array")) { String[] pn = new String[] { null, "MarkMarkPos" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } } else if (en[1].equals("Mark1Coverage")) { @@ -1220,7 +1213,7 @@ public class TTXFile { } } else if (en[1].equals("Mark2Array")) { String[] pn = new String[] { null, "MarkMarkPos" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } } else if (en[1].equals("Mark2Coverage")) { @@ -1273,7 +1266,7 @@ public class TTXFile { String[] pn1 = new String[] { null, "MarkBasePos" }; String[] pn2 = new String[] { null, "MarkLigPos" }; String[][] pnx = new String[][] { pn1, pn2 }; - if (! isParent(pnx)) { + if (!isParent(pnx)) { notPermittedInElementContext(en, getParent(), pnx); } } else if (en[1].equals("MarkAttachClassDef")) { @@ -1549,14 +1542,14 @@ public class TTXFile { } } else if (en[1].equals("Script")) { String[] pn = new String[] { null, "ScriptRecord" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } } else if (en[1].equals("ScriptList")) { String[] pn1 = new String[] { null, "GSUB" }; String[] pn2 = new String[] { null, "GPOS" }; String[][] pnx = new String[][] { pn1, pn2 }; - if (! isParent(pnx)) { + if (!isParent(pnx)) { notPermittedInElementContext(en, getParent(), pnx); } } else if (en[1].equals("ScriptRecord")) { @@ -1890,7 +1883,7 @@ public class TTXFile { } } else if (en[1].equals("cmap")) { String[] pn = new String[] { null, "ttFont" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } } else if (en[1].equals("cmap_format_0")) { @@ -1997,12 +1990,12 @@ public class TTXFile { } } else if (en[1].equals("head")) { String[] pn = new String[] { null, "ttFont" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } } else if (en[1].equals("hmtx")) { String[] pn = new String[] { null, "ttFont" }; - if (! isParent(pn)) { + if (!isParent(pn)) { notPermittedInElementContext(en, getParent(), pn); } else if (glyphIdMax > 0) { hmtxEntries.setSize(glyphIdMax + 1); @@ -2216,7 +2209,7 @@ public class TTXFile { throw new SAXException("element stack is empty, elements are not balanced"); } String[] en = makeExpandedName(uri, localName, qName); - if (! sameExpandedName(enParent, en)) { + if (!sameExpandedName(enParent, en)) { throw new SAXException("element stack is unbalanced, expanded name mismatch"); } if (en[0] != null) { @@ -2244,7 +2237,7 @@ public class TTXFile { } else if (en[1].equals("AlternateSet")) { subtableEntries.add(extractAlternates()); } else if (en[1].equals("AlternateSubst")) { - if (! sortEntries(coverageEntries, subtableEntries)) { + if (!sortEntries(coverageEntries, subtableEntries)) { mismatchedEntries(en, coverageEntries.size(), subtableEntries.size()); } addGSUBSubtable(GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_ALTERNATE, extractCoverage()); @@ -2262,9 +2255,9 @@ public class TTXFile { } else if (en[1].equals("ChainContextPos") || en[1].equals("ChainContextSubst")) { GlyphCoverageTable coverage = null; if (stFormat == 3) { - GlyphCoverageTable igca[] = getCoveragesWithPrefix("in"); - GlyphCoverageTable bgca[] = getCoveragesWithPrefix("bk"); - GlyphCoverageTable lgca[] = getCoveragesWithPrefix("la"); + GlyphCoverageTable[] igca = getCoveragesWithPrefix("in"); + GlyphCoverageTable[] bgca = getCoveragesWithPrefix("bk"); + GlyphCoverageTable[] lgca = getCoveragesWithPrefix("la"); if ((igca.length == 0) || hasMissingCoverage(igca)) { missingCoverage(en, "input", igca.length); } else if (hasMissingCoverage(bgca)) { @@ -2363,7 +2356,7 @@ public class TTXFile { } else if (en[1].equals("LigatureSet")) { subtableEntries.add(extractLigatures()); } else if (en[1].equals("LigatureSubst")) { - if (! sortEntries(coverageEntries, subtableEntries)) { + if (!sortEntries(coverageEntries, subtableEntries)) { mismatchedEntries(en, coverageEntries.size(), subtableEntries.size()); } GlyphCoverageTable coverage = extractCoverage(); @@ -2475,7 +2468,8 @@ public class TTXFile { } GlyphCoverageTable coverage = coverages.get("main"); addGPOSSubtable(GlyphPositioningTable.GPOS_LOOKUP_TYPE_PAIR, coverage); - vf1 = vf2 = -1; psIndex = -1; + vf1 = vf2 = -1; + psIndex = -1; } else if (en[1].equals("PairSet")) { if (psIndex != pairSets.size()) { invalidIndex(en, psIndex, pairSets.size()); @@ -2528,7 +2522,7 @@ public class TTXFile { addGPOSSubtable(GlyphPositioningTable.GPOS_LOOKUP_TYPE_SINGLE, coverage); vf1 = -1; } else if (en[1].equals("SingleSubst")) { - if (! sortEntries(coverageEntries, subtableEntries)) { + if (!sortEntries(coverageEntries, subtableEntries)) { mismatchedEntries(en, coverageEntries.size(), subtableEntries.size()); } GlyphCoverageTable coverage = extractCoverage(); @@ -2556,7 +2550,7 @@ public class TTXFile { public void characters(char[] chars, int start, int length) { } private String[] getParent() { - if (! elements.empty()) { + if (!elements.empty()) { return elements.peek(); } else { return new String[] { null, null }; @@ -2572,13 +2566,11 @@ public class TTXFile { return false; } else if (enx instanceof String[]) { String[] en = (String[]) enx; - if (! elements.empty()) { + if (!elements.empty()) { String[] pn = elements.peek(); return (pn != null) && sameExpandedName(en, pn); - } else if ((en[0] == null) && (en[1] == null)) { - return true; } else { - return false; + return ((en[0] == null) && (en[1] == null)); } } else { return false; @@ -2595,14 +2587,12 @@ public class TTXFile { return true; } else if (ln.equals("MarkAnchor")) { return true; - } else if (ln.equals("Mark2Anchor")) { - return true; } else { - return false; + return ln.equals("Mark2Anchor"); } } - private Map<Integer,Integer> getCMAP() { - Map<Integer,Integer> cmap = new TreeMap(); + private Map<Integer, Integer> getCMAP() { + Map<Integer, Integer> cmap = new TreeMap(); for (int[] cme : cmapEntries) { Integer c = Integer.valueOf(cme[0]); Integer g = Integer.valueOf(cme[1]); @@ -2610,8 +2600,8 @@ public class TTXFile { } return cmap; } - private Map<Integer,Integer> getGMAP() { - Map<Integer,Integer> gmap = new TreeMap(); + private Map<Integer, Integer> getGMAP() { + Map<Integer, Integer> gmap = new TreeMap(); for (int[] cme : cmapEntries) { Integer c = Integer.valueOf(cme[0]); Integer g = Integer.valueOf(cme[1]); @@ -2631,7 +2621,7 @@ public class TTXFile { } return hmtx; } - private GlyphClassTable extractClassDefMapping(Map<String,Integer> glyphClasses, int format, boolean clearSourceMap) { + private GlyphClassTable extractClassDefMapping(Map<String, Integer> glyphClasses, int format, boolean clearSourceMap) { GlyphClassTable ct; if (format == 1) { ct = extractClassDefMapping1(extractClassMappings(glyphClasses, clearSourceMap)); @@ -2685,11 +2675,11 @@ public class TTXFile { } return GlyphClassTable.createClassTable(entries); } - private int[][] extractClassMappings(Map<String,Integer> glyphClasses, boolean clearSourceMap) { + private int[][] extractClassMappings(Map<String, Integer> glyphClasses, boolean clearSourceMap) { int nc = glyphClasses.size(); int i = 0; int[][] cma = new int [ nc ] [ 2 ]; - for (Map.Entry<String,Integer> e : glyphClasses.entrySet()) { + for (Map.Entry<String, Integer> e : glyphClasses.entrySet()) { Integer gid = glyphIds.get(e.getKey()); assert gid != null; int[] m = cma [ i ]; @@ -2856,8 +2846,8 @@ public class TTXFile { private void clearLanguageFeatures() { languageFeatures.clear(); } - private Map<String,List<String>> extractLanguages() { - Map<String,List<String>> lm = new HashMap(languages); + private Map<String, List<String>> extractLanguages() { + Map<String, List<String>> lm = new HashMap(languages); clearLanguages(); return lm; } @@ -2923,10 +2913,10 @@ public class TTXFile { ltFlags = 0; clearSubtablesInLookup(); } - private Map<GlyphTable.LookupSpec,List<String>> extractLookups() { - Map<GlyphTable.LookupSpec,List<String>> lookups = new LinkedHashMap<GlyphTable.LookupSpec,List<String>>(); + private Map<GlyphTable.LookupSpec, List<String>> extractLookups() { + Map<GlyphTable.LookupSpec, List<String>> lookups = new LinkedHashMap<GlyphTable.LookupSpec, List<String>>(); for (String st : scripts.keySet()) { - Map<String,List<String>> lm = scripts.get(st); + Map<String, List<String>> lm = scripts.get(st); if (lm != null) { for (String lt : lm.keySet()) { List<String> fids = lm.get(lt); @@ -3062,7 +3052,7 @@ public class TTXFile { missingParameter(en, "xAdvance"); } String yAdvance = attrs.getValue("YAdvance"); - int ya = 0;; + int ya = 0; if (yAdvance != null) { ya = Integer.parseInt(yAdvance); } else if ((format & GlyphPositioningTable.Value.Y_ADVANCE) != 0) { @@ -3207,7 +3197,7 @@ public class TTXFile { if (cm != null) { for (Anchor[] aa : cm) { if (aa != null) { - int nc = aa.length;; + int nc = aa.length; if (nc > ncMax) { ncMax = nc; } @@ -3223,7 +3213,7 @@ public class TTXFile { if (lam != null) { for (Anchor[][] cm : lam) { if (cm != null) { - int nx = cm.length;; + int nx = cm.length; if (nx > nxMax) { nxMax = nx; } @@ -3424,7 +3414,7 @@ public class TTXFile { return false; } if ((u1 != null) && (u2 != null)) { - if (! u1.equals(u2)) { + if (!u1.equals(u2)) { return false; } } @@ -3434,7 +3424,7 @@ public class TTXFile { return false; } if ((l1 != null) && (l2 != null)) { - if (! l1.equals(l2)) { + if (!l1.equals(l2)) { return false; } } diff --git a/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java b/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java index cf5d846b4..c48be5220 100644 --- a/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java +++ b/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java @@ -29,8 +29,6 @@ import org.apache.fop.complexscripts.scripts.arabic.ArabicTestCase; * Test suite for script specific functionality related to complex scripts. */ @RunWith(Suite.class) -@SuiteClasses({ - ArabicTestCase.class -}) +@SuiteClasses(ArabicTestCase.class) public class ScriptsTestSuite { } diff --git a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java index d34e88a03..8542faae9 100644 --- a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java +++ b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java @@ -21,30 +21,26 @@ package org.apache.fop.complexscripts.scripts.arabic; import java.io.File; import java.io.FileInputStream; -import java.io.FilenameFilter; import java.io.FileNotFoundException; -import java.io.FileOutputStream; +import java.io.FilenameFilter; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.LineNumberReader; import java.io.ObjectInputStream; import java.nio.IntBuffer; -import java.nio.charset.Charset; -import java.util.ArrayList; import java.util.List; -import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; -import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable; -import org.apache.fop.complexscripts.fonts.ttx.TTXFile; -import org.apache.fop.complexscripts.util.GlyphSequence; - -import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; +import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable; +import org.apache.fop.complexscripts.fonts.ttx.TTXFile; +import org.apache.fop.complexscripts.util.GlyphSequence; + +// CSOFF: LineLength + /** * Tests for functionality related to the arabic script. */ @@ -52,9 +48,9 @@ public class ArabicTestCase implements ArabicTestConstants { @Test public void testArabicWordForms() { - for (String sfn : srcFiles) { + for (String sfn : SRC_FILES) { try { - processWordForms(new File(datFilesDir)); + processWordForms(new File(DAT_FILES_DIR)); } catch (Exception e) { fail(e.getMessage()); } @@ -72,7 +68,7 @@ public class ArabicTestCase implements ArabicTestConstants { private String[] listWordFormFiles(File dfd) { return dfd.list(new FilenameFilter() { public boolean accept(File f, String name) { - return hasPrefixFrom(name, srcFiles) && hasExtension(name, WF_FILE_DAT_EXT); + return hasPrefixFrom(name, SRC_FILES) && hasExtension(name, WF_FILE_DAT_EXT); } private boolean hasPrefixFrom(String name, String[] prefixes) { for (String p : prefixes) { @@ -108,7 +104,7 @@ public class ArabicTestCase implements ArabicTestConstants { throw new RuntimeException(e.getMessage(), e); } finally { if (fis != null) { - try { fis.close(); } catch (Exception e) {} + try { fis.close(); } catch (Exception e) { /* NOP */ } } } } @@ -129,7 +125,7 @@ public class ArabicTestCase implements ArabicTestConstants { script = (String) d[0]; language = (String) d[1]; tfn = (String) d[3]; - tf = TTXFile.getFromCache(ttxFontsDir + File.separator + tfn); + tf = TTXFile.getFromCache(TTX_FONTS_DIR + File.separator + tfn); assertTrue(tf != null); gsub = tf.getGSUB(); assertTrue(gsub != null); diff --git a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java index 0669ff137..cc9167553 100644 --- a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java +++ b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java @@ -24,22 +24,22 @@ package org.apache.fop.complexscripts.scripts.arabic; */ public interface ArabicTestConstants { - final String WF_FILE_SCRIPT = "arab"; - final String WF_FILE_LANGUAGE = "dflt"; + String WF_FILE_SCRIPT = "arab"; + String WF_FILE_LANGUAGE = "dflt"; - String srcFilesDir = "test/resources/complexscripts/arab/data"; - String datFilesDir = "test/resources/complexscripts/arab/data"; + String SRC_FILES_DIR = "test/resources/complexscripts/arab/data"; + String DAT_FILES_DIR = "test/resources/complexscripts/arab/data"; - String[] srcFiles = { + String[] SRC_FILES = { "arab-001", // unpointed word forms }; - final String WF_FILE_SRC_EXT = "txt"; - final String WF_FILE_DAT_EXT = "ser"; + String WF_FILE_SRC_EXT = "txt"; + String WF_FILE_DAT_EXT = "ser"; - String ttxFontsDir = "test/resources/complexscripts/arab/ttx"; + String TTX_FONTS_DIR = "test/resources/complexscripts/arab/ttx"; - String[] ttxFonts = { + String[] TTX_FONTS = { "arab-001.ttx", // simplified arabic "arab-002.ttx", // traditional arabic "arab-003.ttx", // lateef diff --git a/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java b/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java index a4f876dd8..9ca16a164 100644 --- a/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java +++ b/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java @@ -40,7 +40,10 @@ import org.apache.fop.complexscripts.util.GlyphSequence; /** * Tests for functionality related to the arabic script. */ -public class GenerateArabicTestData implements ArabicTestConstants { +public final class GenerateArabicTestData implements ArabicTestConstants { + + private GenerateArabicTestData() { + } public static void main(String[] args) { boolean compile = false; @@ -69,9 +72,9 @@ public class GenerateArabicTestData implements ArabicTestConstants { } private static void compile() { - for (String sfn : srcFiles) { + for (String sfn : SRC_FILES) { try { - String spn = srcFilesDir + File.separator + sfn + "." + WF_FILE_SRC_EXT; + String spn = SRC_FILES_DIR + File.separator + sfn + "." + WF_FILE_SRC_EXT; compile(WF_FILE_SCRIPT, WF_FILE_LANGUAGE, spn); } catch (Exception e) { System.err.println(e.getMessage()); @@ -81,8 +84,8 @@ public class GenerateArabicTestData implements ArabicTestConstants { private static void compile(String script, String language, String spn) { int fno = 0; - for (String tfn : ttxFonts) { - TTXFile tf = TTXFile.getFromCache(ttxFontsDir + File.separator + tfn); + for (String tfn : TTX_FONTS) { + TTXFile tf = TTXFile.getFromCache(TTX_FONTS_DIR + File.separator + tfn); assert tf != null; List data = compile(script, language, spn, tfn, tf); output(makeDataPathName(spn, fno++), data); @@ -106,7 +109,7 @@ public class GenerateArabicTestData implements ArabicTestConstants { GlyphSequence igs = tf.mapCharsToGlyphs(wf); GlyphSequence ogs = gsub.substitute(igs, script, language); int[][] paa = new int [ ogs.getGlyphCount() ] [ 4 ]; - if (! gpos.position(ogs, script, language, 1000, widths, paa)) { + if (!gpos.position(ogs, script, language, 1000, widths, paa)) { paa = null; } data.add(new Object[] { wf, getGlyphs(igs), getGlyphs(ogs), paa }); @@ -121,7 +124,7 @@ public class GenerateArabicTestData implements ArabicTestConstants { throw new RuntimeException(e.getMessage(), e); } finally { if (fis != null) { - try { fis.close(); } catch (Exception e) {} + try { fis.close(); } catch (Exception e) { /* NOP */ } } } } else { @@ -142,7 +145,7 @@ public class GenerateArabicTestData implements ArabicTestConstants { private static String makeDataPathName(String spn, int fno) { File f = new File(spn); - return datFilesDir + File.separator + stripExtension(f.getName()) + "-f" + fno + "." + WF_FILE_DAT_EXT; + return DAT_FILES_DIR + File.separator + stripExtension(f.getName()) + "-f" + fno + "." + WF_FILE_DAT_EXT; } private static String stripExtension(String s) { @@ -171,7 +174,7 @@ public class GenerateArabicTestData implements ArabicTestConstants { throw new RuntimeException(e.getMessage(), e); } finally { if (fos != null) { - try { fos.close(); } catch (Exception e) {} + try { fos.close(); } catch (Exception e) { /* NOP */ } } } } diff --git a/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java b/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java index ea885b6c5..4e1db5fb3 100644 --- a/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java +++ b/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java @@ -30,12 +30,10 @@ import static org.junit.Assert.assertEquals; /** * Test number converter functionality. - * - * @author Glenn Adams */ public class NumberConverterTestCase { - static private String[][] formatDecimal = + private static String[][] formatDecimal = { { "1" }, { "0", "0" }, @@ -45,7 +43,7 @@ public class NumberConverterTestCase { { "1000000000", "1000000000" }, }; - static private String[][] formatDecimalPadded = + private static String[][] formatDecimalPadded = { { "001" }, { "0", "000" }, @@ -58,7 +56,7 @@ public class NumberConverterTestCase { { "1000", "1000" }, }; - static private String[][] formatDecimalGrouped = + private static String[][] formatDecimalGrouped = { { "1", ",", "1" }, { "0", "0" }, @@ -68,7 +66,7 @@ public class NumberConverterTestCase { { "1000000000", "1,0,0,0,0,0,0,0,0,0" }, }; - static private String[][] formatDecimalGroupedPadded = + private static String[][] formatDecimalGroupedPadded = { { "001", ",", "2" }, { "0", "0,00" }, @@ -81,7 +79,7 @@ public class NumberConverterTestCase { { "1000", "10,00" }, }; - static private String[][] formatDecimalArabic = + private static String[][] formatDecimalArabic = { { "\u0661" }, { "0", "\u0660" }, @@ -100,7 +98,7 @@ public class NumberConverterTestCase { { "1000000000", "\u0661\u0660\u0660\u0660\u0660\u0660\u0660\u0660\u0660\u0660" }, }; - static private String[][] formatDecimalArabicPadded = + private static String[][] formatDecimalArabicPadded = { { "\u0660\u0660\u0661" }, { "0", "\u0660\u0660\u0660" }, @@ -113,7 +111,7 @@ public class NumberConverterTestCase { { "1000", "\u0661\u0660\u0660\u0660" }, }; - static private String[][] formatDecimalArabicGrouped = + private static String[][] formatDecimalArabicGrouped = { { "\u0661", "\u066c", "1" }, { "0", "\u0660" }, @@ -123,7 +121,7 @@ public class NumberConverterTestCase { { "1000000000", "\u0661\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660" }, }; - static private String[][] formatDecimalArabicGroupedPadded = + private static String[][] formatDecimalArabicGroupedPadded = { { "\u0660\u0660\u0661", "\u066c", "2" }, { "0", "\u0660\u066c\u0660\u0660" }, @@ -136,7 +134,7 @@ public class NumberConverterTestCase { { "1000", "\u0661\u0660\u066c\u0660\u0660" }, }; - static private String[][] formatDecimalThai = + private static String[][] formatDecimalThai = { { "\u0E51" }, { "0", "\u0E50" }, @@ -155,7 +153,7 @@ public class NumberConverterTestCase { { "1000000000", "\u0E51\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50" }, }; - static private String[][] formatDecimalThaiPadded = + private static String[][] formatDecimalThaiPadded = { { "\u0E50\u0E50\u0E51" }, { "0", "\u0E50\u0E50\u0E50" }, @@ -168,7 +166,7 @@ public class NumberConverterTestCase { { "1000", "\u0E51\u0E50\u0E50\u0E50" }, }; - static private String[][] formatRomanLower = + private static String[][] formatRomanLower = { { "i" }, { "0", "0" }, @@ -206,7 +204,7 @@ public class NumberConverterTestCase { { "5000", "5000" }, }; - static private String[][] formatRomanUpper = + private static String[][] formatRomanUpper = { { "I" }, @@ -245,7 +243,7 @@ public class NumberConverterTestCase { { "5000", "5000" }, }; - static private String[][] formatRomanLargeLower = + private static String[][] formatRomanLargeLower = { { "i", null, null, null, "large" }, { "0", "0" }, @@ -293,7 +291,7 @@ public class NumberConverterTestCase { { "200000", "200000" }, }; - static private String[][] formatRomanLargeUpper = + private static String[][] formatRomanLargeUpper = { { "I", null, null, null, "large" }, { "0", "0" }, @@ -341,7 +339,7 @@ public class NumberConverterTestCase { { "200000", "200000" }, }; - static private String[][] formatRomanNumberFormsLower = + private static String[][] formatRomanNumberFormsLower = { { "i", null, null, null, "unicode-number-forms" }, { "0", "0" }, @@ -399,7 +397,7 @@ public class NumberConverterTestCase { { "200000", "200000" }, }; - static private String[][] formatRomanNumberFormsUpper = + private static String[][] formatRomanNumberFormsUpper = { { "I", null, null, null, "unicode-number-forms" }, { "0", "0" }, @@ -457,7 +455,7 @@ public class NumberConverterTestCase { { "200000", "200000" }, }; - static private String[][] formatAlphabeticLatinLower = + private static String[][] formatAlphabeticLatinLower = { { "a" }, { "0", "0" }, @@ -478,7 +476,7 @@ public class NumberConverterTestCase { { "1000000", "bdwgn" }, }; - static private String[][] formatAlphabeticLatinUpper = + private static String[][] formatAlphabeticLatinUpper = { { "A" }, { "0", "0" }, @@ -499,7 +497,7 @@ public class NumberConverterTestCase { { "1000000", "BDWGN" }, }; - static private String[][] formatAlphabeticArabicHijai = + private static String[][] formatAlphabeticArabicHijai = { { "\u0627", null, null, "alphabetic" }, { "0", "0" }, @@ -540,7 +538,7 @@ public class NumberConverterTestCase { { "1000000", "\u0623\u0638\u0636\u0635\u062F" }, }; - static private String[][] formatAlphabeticArabicAbjadi = + private static String[][] formatAlphabeticArabicAbjadi = { { "\u0627", null, null, "traditional" }, { "0", "0" }, @@ -581,7 +579,7 @@ public class NumberConverterTestCase { { "1000000", "\u0623\u0641\u0633\u0646\u062D" }, }; - static private String[][] formatNumeralArabicAbjadi = + private static String[][] formatNumeralArabicAbjadi = { { "\u0623", null, null, "traditional" }, { "0", "0" }, @@ -629,7 +627,7 @@ public class NumberConverterTestCase { { "2000", "2000" }, }; - static private String[][] formatAlphabeticHebrew = + private static String[][] formatAlphabeticHebrew = { { "\u05D0", null, null, "alphabetic" }, { "0", "0" }, @@ -669,7 +667,7 @@ public class NumberConverterTestCase { { "1000000", "\u05D0\u05DA\u05E9\u05E8\u05D0" }, }; - static private String[][] formatNumeralHebrewGematria = + private static String[][] formatNumeralHebrewGematria = { { "\u05D0", null, null, "traditional" }, { "0", "0" }, @@ -717,7 +715,7 @@ public class NumberConverterTestCase { { "2000", "2000" }, }; - static private String[][] formatAlphabeticThai = + private static String[][] formatAlphabeticThai = { { "\u0E01", null, null, "alphabetic" }, { "0", "0" }, @@ -738,7 +736,7 @@ public class NumberConverterTestCase { { "1000000", "\u0E0B\u0E20\u0E17\u0E0C" }, }; - static private String[][] formatWordEnglishLower = + private static String[][] formatWordEnglishLower = { { "w", null, null, null, null, "eng" }, { "0", "zero" }, @@ -762,7 +760,7 @@ public class NumberConverterTestCase { { "1000000000", "one billion" } }; - static private String[][] formatWordEnglishUpper = + private static String[][] formatWordEnglishUpper = { { "W", null, null, null, null, "eng" }, { "0", "ZERO" }, @@ -786,7 +784,7 @@ public class NumberConverterTestCase { { "1000000000", "ONE BILLION" } }; - static private String[][] formatWordEnglishTitle = + private static String[][] formatWordEnglishTitle = { { "Ww", null, null, null, null, "eng" }, { "0", "Zero" }, @@ -810,7 +808,7 @@ public class NumberConverterTestCase { { "1000000000", "One Billion" } }; - static private String[][] formatWordSpanishLower = + private static String[][] formatWordSpanishLower = { { "w", null, null, null, null, "spa" }, { "0", "cero" }, @@ -890,7 +888,7 @@ public class NumberConverterTestCase { { "1000000000", "mil millones" } }; - static private String[][] formatWordSpanishUpper = + private static String[][] formatWordSpanishUpper = { { "W", null, null, null, null, "spa" }, { "0", "CERO" }, @@ -970,7 +968,7 @@ public class NumberConverterTestCase { { "1000000000", "MIL MILLONES" } }; - static private String[][] formatWordSpanishTitle = + private static String[][] formatWordSpanishTitle = { { "Ww", null, null, null, null, "spa" }, { "0", "Cero" }, @@ -1050,7 +1048,7 @@ public class NumberConverterTestCase { { "1000000000", "Mil Millones" } }; - static private String[][] formatWordFrenchLower = + private static String[][] formatWordFrenchLower = { { "w", null, null, null, null, "fra" }, { "0", "z\u00e9ro" }, @@ -1141,7 +1139,7 @@ public class NumberConverterTestCase { { "1000000000", "un milliard" } }; - static private String[][] formatWordFrenchUpper = + private static String[][] formatWordFrenchUpper = { { "W", null, null, null, null, "fra" }, { "0", "Z\u00c9RO" }, @@ -1232,7 +1230,7 @@ public class NumberConverterTestCase { { "1000000000", "UN MILLIARD" } }; - static private String[][] formatWordFrenchTitle = + private static String[][] formatWordFrenchTitle = { { "Ww", null, null, null, null, "fra" }, { "0", "Z\u00e9ro" }, diff --git a/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java b/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java index 70bd568af..4407254a8 100644 --- a/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java +++ b/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java @@ -27,8 +27,6 @@ import org.junit.runners.Suite.SuiteClasses; * Test suite for bidirectional functionality. */ @RunWith(Suite.class) -@SuiteClasses({ - NumberConverterTestCase.class -}) +@SuiteClasses(NumberConverterTestCase.class) public class UtilTestSuite { } diff --git a/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java b/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java index 8d7d46928..fa4babfa2 100644 --- a/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java +++ b/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java @@ -24,7 +24,6 @@ import java.io.IOException; import org.xml.sax.SAXException; import org.apache.fop.apps.FopConfBuilder; -import org.apache.fop.apps.MimeConstants; import org.apache.fop.apps.PDFRendererConfBuilder; /** diff --git a/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java b/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java index 84e8ee804..591104412 100644 --- a/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java +++ b/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java @@ -24,7 +24,6 @@ import java.io.IOException; import org.xml.sax.SAXException; import org.apache.fop.apps.FopConfBuilder; -import org.apache.fop.apps.MimeConstants; import org.apache.fop.apps.PDFRendererConfBuilder; /** diff --git a/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java b/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java index 3479c3794..11538dc33 100644 --- a/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java +++ b/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java @@ -24,7 +24,6 @@ import java.io.IOException; import org.xml.sax.SAXException; import org.apache.fop.apps.FopConfBuilder; -import org.apache.fop.apps.MimeConstants; import org.apache.fop.apps.PDFRendererConfBuilder; /** diff --git a/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java b/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java index 800e06d32..4bacc180c 100644 --- a/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java +++ b/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java @@ -24,7 +24,6 @@ import java.io.IOException; import org.xml.sax.SAXException; import org.apache.fop.apps.FopConfBuilder; -import org.apache.fop.apps.MimeConstants; import org.apache.fop.apps.PDFRendererConfBuilder; /** diff --git a/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java b/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java index c9f6d98ff..e05e44ab1 100644 --- a/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java +++ b/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java @@ -24,7 +24,6 @@ import java.io.IOException; import org.xml.sax.SAXException; import org.apache.fop.apps.FopConfBuilder; -import org.apache.fop.apps.MimeConstants; import org.apache.fop.apps.PDFRendererConfBuilder; public class FontsAutoDetectTestCase extends BaseConstructiveUserConfigTest { diff --git a/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java b/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java index 2776c2cce..aab7a2e7c 100644 --- a/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java +++ b/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java @@ -24,7 +24,6 @@ import java.io.IOException; import org.xml.sax.SAXException; import org.apache.fop.apps.FopConfBuilder; -import org.apache.fop.apps.MimeConstants; import org.apache.fop.apps.PDFRendererConfBuilder; /** diff --git a/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java b/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java index 23af20a1a..f6e2b02ba 100644 --- a/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java +++ b/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java @@ -19,10 +19,10 @@ package org.apache.fop.datatypes; -import static org.junit.Assert.assertEquals; - import org.junit.Test; +import static org.junit.Assert.assertEquals; + /** * Tests for URISpecification. */ diff --git a/test/java/org/apache/fop/events/BasicEventTestCase.java b/test/java/org/apache/fop/events/BasicEventTestCase.java index 87fc04329..39e3fec98 100644 --- a/test/java/org/apache/fop/events/BasicEventTestCase.java +++ b/test/java/org/apache/fop/events/BasicEventTestCase.java @@ -19,6 +19,8 @@ package org.apache.fop.events; +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -26,7 +28,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.apache.fop.events.model.EventSeverity; -import org.junit.Test; public class BasicEventTestCase { diff --git a/test/java/org/apache/fop/events/EventChecker.java b/test/java/org/apache/fop/events/EventChecker.java index 3f0eef6bb..506658467 100644 --- a/test/java/org/apache/fop/events/EventChecker.java +++ b/test/java/org/apache/fop/events/EventChecker.java @@ -27,7 +27,7 @@ import static org.junit.Assert.fail; /** * Class that checks that an expected event is produced, and only this one. */ -class EventChecker implements EventListener { +public class EventChecker implements EventListener { private final String expectedEventID; @@ -35,7 +35,7 @@ class EventChecker implements EventListener { private boolean eventReceived; - EventChecker(String expectedEventID, Map<String, Object> expectedParams) { + public EventChecker(String expectedEventID, Map<String, Object> expectedParams) { this.expectedEventID = expectedEventID; this.expectedParams = expectedParams; } @@ -51,9 +51,9 @@ class EventChecker implements EventListener { } } - void end() { + public void end() { if (!eventReceived) { - fail("Did not received expected event: " + expectedEventID); + fail("Did not receive expected event: " + expectedEventID); } } } diff --git a/test/java/org/apache/fop/events/TestEventProducer.java b/test/java/org/apache/fop/events/TestEventProducer.java index ff0bc2a81..ff19c7ea6 100644 --- a/test/java/org/apache/fop/events/TestEventProducer.java +++ b/test/java/org/apache/fop/events/TestEventProducer.java @@ -38,7 +38,10 @@ public interface TestEventProducer extends EventProducer { */ void enjoy(Object source, String what); - public class Provider { + public static final class Provider { + + private Provider() { + } public static TestEventProducer get(EventBroadcaster broadcaster) { return (TestEventProducer)broadcaster.getEventProducerFor(TestEventProducer.class); diff --git a/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java index 313379e02..226c551fb 100644 --- a/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java +++ b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java @@ -19,8 +19,6 @@ package org.apache.fop.fo; -import static org.junit.Assert.assertArrayEquals; - import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -42,6 +40,8 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; +import static org.junit.Assert.assertArrayEquals; + import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory; import org.apache.fop.fo.flow.BasicLink; diff --git a/test/java/org/apache/fop/fo/FODocumentParser.java b/test/java/org/apache/fop/fo/FODocumentParser.java index 7d03e38a6..2e691519b 100644 --- a/test/java/org/apache/fop/fo/FODocumentParser.java +++ b/test/java/org/apache/fop/fo/FODocumentParser.java @@ -64,7 +64,7 @@ public final class FODocumentParser { /** * A factory to create custom instances of {@link FOEventHandler}. */ - public static interface FOEventHandlerFactory { + public interface FOEventHandlerFactory { /** * Creates a new {@code FOEventHandler} instance parameterized with the given FO user agent. diff --git a/test/java/org/apache/fop/fo/FONodeMocks.java b/test/java/org/apache/fop/fo/FONodeMocks.java index ba969b9fa..97889c177 100644 --- a/test/java/org/apache/fop/fo/FONodeMocks.java +++ b/test/java/org/apache/fop/fo/FONodeMocks.java @@ -31,7 +31,6 @@ import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.FopFactory; import org.apache.fop.events.EventBroadcaster; import org.apache.fop.fo.flow.table.ColumnNumberManager; import org.apache.fop.fo.flow.table.ColumnNumberManagerHolder; @@ -46,7 +45,7 @@ public final class FONodeMocks { /** * Creates and returns a mock {@link FONode} configured with a mock * {@link FOEventHandler}. The FO event handler returns a mock {@link FOUserAgent}, - * which in turn returns a mock {@link FopFactory}, which returns a mock + * which in turn returns a mock {@link org.apache.fop.apps.FopFactory}, which returns a mock * {@link ImageManager}. * * @return a mock FO node diff --git a/test/java/org/apache/fop/fo/flow/MarkersTestCase.java b/test/java/org/apache/fop/fo/flow/MarkersTestCase.java index 983a531b0..09a4e129c 100644 --- a/test/java/org/apache/fop/fo/flow/MarkersTestCase.java +++ b/test/java/org/apache/fop/fo/flow/MarkersTestCase.java @@ -30,10 +30,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.apache.fop.fo.Constants; -import org.apache.fop.fo.flow.Marker; -import org.apache.fop.fo.flow.Markers; -import org.apache.fop.fo.flow.RetrieveMarker; -import org.apache.fop.fo.flow.RetrieveTableMarker; public class MarkersTestCase { diff --git a/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java b/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java index fb6ec6a25..0f0e347d3 100644 --- a/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java +++ b/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java @@ -24,8 +24,8 @@ import java.util.Iterator; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.FODocumentParser; -import org.apache.fop.fo.FOEventHandler; import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory; +import org.apache.fop.fo.FOEventHandler; import org.apache.fop.util.ConsoleEventListenerForTests; /** diff --git a/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java b/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java index 7c0301ca7..75ba53525 100644 --- a/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java @@ -19,18 +19,20 @@ package org.apache.fop.fo.flow.table; -import static org.junit.Assert.assertEquals; - import java.awt.Color; import java.util.Iterator; import java.util.List; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode.FONodeIterator; import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; +// CSOFF: LineLength + /** * A testcase for the resolution of collapsed borders in the FO tree, taking * conditionality into account. The resolved borders are generated by the diff --git a/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java b/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java index 361517a66..884116441 100644 --- a/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java @@ -19,16 +19,16 @@ package org.apache.fop.fo.flow.table; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - import java.util.Iterator; import java.util.List; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + /** * Tests that RowGroupBuilder returns, for each part of a table, the expected number of * row-groups with the expected number or rows in each. diff --git a/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java b/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java index a21806559..2df0cac2a 100644 --- a/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java @@ -19,12 +19,12 @@ package org.apache.fop.fo.flow.table; -import static org.junit.Assert.assertEquals; - import java.util.Iterator; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.fo.FObj; diff --git a/test/java/org/apache/fop/fo/flow/table/TableHandler.java b/test/java/org/apache/fop/fo/flow/table/TableHandler.java index 11f24b99b..04da32b47 100644 --- a/test/java/org/apache/fop/fo/flow/table/TableHandler.java +++ b/test/java/org/apache/fop/fo/flow/table/TableHandler.java @@ -24,7 +24,6 @@ import java.util.List; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.FOEventHandler; -import org.apache.fop.fo.flow.table.Table; public class TableHandler extends FOEventHandler { diff --git a/test/java/org/apache/fop/fo/pagination/AllTests.java b/test/java/org/apache/fop/fo/pagination/AllTests.java index 40990cb06..bd5b21c14 100644 --- a/test/java/org/apache/fop/fo/pagination/AllTests.java +++ b/test/java/org/apache/fop/fo/pagination/AllTests.java @@ -19,8 +19,8 @@ package org.apache.fop.fo.pagination; -import org.junit.runners.Suite; import org.junit.runner.RunWith; +import org.junit.runners.Suite; /** * All test to be added in FOTreeTestSuite @@ -28,6 +28,6 @@ import org.junit.runner.RunWith; */ @RunWith(Suite.class) @Suite.SuiteClasses({ PageSequenceMasterTestCase.class, - RepeatablePageMasterAlternativesTestCase.class}) + RepeatablePageMasterAlternativesTestCase.class }) public final class AllTests { } diff --git a/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java b/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java index ad4f991ac..d7bc2e11c 100644 --- a/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java +++ b/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java @@ -19,8 +19,10 @@ package org.apache.fop.fo.pagination; -import static org.junit.Assert.fail; +import org.junit.Test; +import org.xml.sax.Locator; +import static org.junit.Assert.fail; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyObject; @@ -33,8 +35,6 @@ import static org.mockito.Mockito.when; import org.apache.fop.apps.FOPException; import org.apache.fop.fo.FONode; import org.apache.fop.layoutmgr.BlockLevelEventProducer; -import org.junit.Test; -import org.xml.sax.Locator; /** diff --git a/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java b/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java index 5ac4860dc..ce1a97638 100644 --- a/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java +++ b/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java @@ -19,6 +19,8 @@ package org.apache.fop.fo.pagination; +import org.junit.Test; + import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; @@ -30,8 +32,6 @@ import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.expr.NumericProperty; import org.apache.fop.fo.properties.Property; -import org.junit.Test; - /** * Unit Test for RepeatablePageMasterAlternatives * diff --git a/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java b/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java index cd5d545ff..89ed2733d 100644 --- a/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java +++ b/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java @@ -19,12 +19,12 @@ package org.apache.fop.fo.properties; +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.junit.Test; - import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.Constants; diff --git a/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java b/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java index 352a39713..81ebc2f41 100644 --- a/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java +++ b/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java @@ -19,16 +19,16 @@ package org.apache.fop.fo.properties; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; import org.apache.fop.fo.FONodeMocks; diff --git a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java index 20212b002..4c89d00da 100644 --- a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java +++ b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java @@ -24,11 +24,11 @@ import java.io.File; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.fop.apps.io.InternalResourceResolver; import org.apache.fop.apps.io.ResourceResolverFactory; -import static org.junit.Assert.assertEquals; - /** * */ @@ -58,4 +58,17 @@ public class DejaVuLGCSerifTestCase { public void testFontName() { assertEquals("DejaVuLGCSerif", font.getFontName()); } + + @Test + public void testUnderline() { + assertEquals(-840, font.getUnderlinePosition(10)); + assertEquals(430, font.getUnderlineThickness(10)); + } + + @Test + public void testStrikeout() { + assertEquals(2340, font.getStrikeoutPosition(10)); + assertEquals(490, font.getStrikeoutThickness(10)); + } + } diff --git a/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java b/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java index ee3498a03..c8099f860 100644 --- a/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java +++ b/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java @@ -35,7 +35,7 @@ import static org.junit.Assert.assertTrue; */ public class EmbedFontInfoTestCase { - public EmbedFontInfoTestCase() {} + public EmbedFontInfoTestCase() { } private EmbedFontInfo sut; diff --git a/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java b/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java index 509ee56f4..b4271ba60 100644 --- a/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java +++ b/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java @@ -52,13 +52,4 @@ public class FontEventProcessingTestCase { MimeConstants.MIME_PDF); } - @Test - public void testSVGFontStrokedAsShapes() throws Exception { - // svg-fonts.fo embeds two fonts; one that is present in the system and the other is not; the - // missing font is stroked as shapes while the fonts that exists is stroked as text - InputStream inStream = getClass().getResourceAsStream("svg-fonts.fo"); - eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".svgTextStrokedAsShapes", - MimeConstants.MIME_PDF); - } - } diff --git a/test/java/org/apache/fop/fonts/FontManagerConfiguratorTestCase.java b/test/java/org/apache/fop/fonts/FontManagerConfiguratorTestCase.java index 073743c13..d653171b7 100644 --- a/test/java/org/apache/fop/fonts/FontManagerConfiguratorTestCase.java +++ b/test/java/org/apache/fop/fonts/FontManagerConfiguratorTestCase.java @@ -20,7 +20,6 @@ package org.apache.fop.fonts; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; @@ -28,13 +27,14 @@ import org.junit.Before; import org.junit.Test; import org.xml.sax.SAXException; +import static org.junit.Assert.assertEquals; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FopConfBuilder; import org.apache.fop.apps.FopConfParser; import org.apache.fop.apps.FopFactory; import static org.apache.fop.apps.FopConfParserTestCase.getFopFactory; -import static org.junit.Assert.assertEquals; /** * A test case for {@link FontManagerConfigurator}. @@ -84,7 +84,7 @@ public class FontManagerConfiguratorTestCase { /** * This test is an interesting one; it's basically testing that if a base URI pointing to a * directory that doesn't exist is used, an error is not thrown. The URI resolver should handle - * any {@link FileNotFoundException}s, not the configuration. We're NOT testing whether a font + * any {@link java.io.FileNotFoundException}s, not the configuration. We're NOT testing whether a font * can be resolved here, just that the URI resolver accepts it as its base URI. */ @Test diff --git a/test/java/org/apache/fop/fonts/cff/CFFDataReaderTestCase.java b/test/java/org/apache/fop/fonts/cff/CFFDataReaderTestCase.java index 64c7642eb..97ea5c52b 100644 --- a/test/java/org/apache/fop/fonts/cff/CFFDataReaderTestCase.java +++ b/test/java/org/apache/fop/fonts/cff/CFFDataReaderTestCase.java @@ -26,14 +26,14 @@ import java.util.Random; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.fontbox.cff.CFFDataInput; import org.apache.fop.fonts.cff.CFFDataReader.CFFIndexData; import org.apache.fop.fonts.cff.CFFDataReader.DICTEntry; import org.apache.fop.fonts.truetype.OTFSubSetFile; -import static org.junit.Assert.assertEquals; - public class CFFDataReaderTestCase { private CFFDataReader cffReader; @@ -113,7 +113,7 @@ public class CFFDataReaderTestCase { //Array comparison int[] fontBBox = { -50, -40, 100, 120 }; DICTEntry fontBBoxEntry = dictMap.get("FontBBox"); - for (int i = 0;i < fontBBoxEntry.getOperands().size();i++) { + for (int i = 0; i < fontBBoxEntry.getOperands().size(); i++) { assertEquals(fontBBoxEntry.getOperands().get(i).intValue(), fontBBox[i]); } //Multi-byte offset (number) @@ -141,7 +141,7 @@ public class CFFDataReaderTestCase { }; Random randGen = new Random(); byte[] data = new byte[31]; - for (int i = 0;i < data.length;i++) { + for (int i = 0; i < data.length; i++) { data[i] = (byte)randGen.nextInt(255); } testIndex = OTFSubSetFile.concatArray(testIndex, data); diff --git a/test/java/org/apache/fop/fonts/svg-fonts.fo b/test/java/org/apache/fop/fonts/svg-fonts.fo deleted file mode 100644 index 0c5f3f599..000000000 --- a/test/java/org/apache/fop/fonts/svg-fonts.fo +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg"> - <fo:layout-master-set> - <fo:simple-page-master master-name="page"> - <fo:region-body /> - </fo:simple-page-master> - </fo:layout-master-set> - <fo:page-sequence master-reference="page"> - <fo:flow flow-name="xsl-region-body"> - <fo:block> - <fo:instream-foreign-object> - <svg:svg width="250" height="50"> - <svg:font horiz-adv-x="1000"> - <svg:font-face font-family="Missing" units-per-em="1000" underline-position="-100" - underline-thickness="50" /> - <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" /> - <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" /> - <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" /> - <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" /> - </svg:font> - <svg:font horiz-adv-x="1000"> - <!-- this is not Helvetica but it is here to increase coverage and show the code takes expected path --> - <svg:font-face font-family="Helvetica" units-per-em="1000" underline-position="-100" - underline-thickness="50" /> - <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" /> - <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" /> - <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" /> - <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" /> - </svg:font> - <svg:text x="20" y="20" font-family="Missing" font-size="12">ACFG</svg:text> - <svg:text x="20" y="40" font-family="Helvetica" font-size="12">ACFG</svg:text> - </svg:svg> - </fo:instream-foreign-object> - </fo:block> - </fo:flow> - </fo:page-sequence> -</fo:root> diff --git a/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java index e794ab1a8..952c3ec1f 100644 --- a/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java +++ b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java @@ -37,7 +37,7 @@ import static org.junit.Assert.assertTrue; */ public class GlyfTableTestCase { - private final static class DirData { + private static final class DirData { final long offset; final long length; diff --git a/test/java/org/apache/fop/fonts/truetype/OTFFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/OTFFileTestCase.java index 737c2e05e..b4e2cee2e 100644 --- a/test/java/org/apache/fop/fonts/truetype/OTFFileTestCase.java +++ b/test/java/org/apache/fop/fonts/truetype/OTFFileTestCase.java @@ -20,7 +20,6 @@ package org.apache.fop.fonts.truetype; import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; import org.junit.Before; @@ -37,7 +36,7 @@ public class OTFFileTestCase { /** * Initializes fonts used for the testing of reading OTF CFF - * @throws IOException + * @throws java.io.IOException */ @Before public void setUp() throws Exception { @@ -75,11 +74,11 @@ public class OTFFileTestCase { int[] gids = {32, 42, 44, 47}; int[] sourceSansWidths = {516, 555, 572, 383}; - for (int i = 0;i < gids.length;i++) { + for (int i = 0; i < gids.length; i++) { assertEquals(sourceSansWidths[i], sourceSansProBold.getWidths()[gids[i]]); } int[] carolynaWidths = {842, 822, 658, 784}; - for (int i = 0;i < gids.length;i++) { + for (int i = 0; i < gids.length; i++) { assertEquals(carolynaWidths[i], alexBrush.getWidths()[gids[i]]); } } diff --git a/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java index 604cca3a8..fecb1e9f1 100644 --- a/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java +++ b/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java @@ -20,6 +20,8 @@ package org.apache.fop.fonts.truetype; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -27,18 +29,15 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; -import org.apache.fontbox.cff.CFFDataInput; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import org.apache.fontbox.cff.CFFFont; -import org.apache.fontbox.cff.CFFParser; -import org.apache.fontbox.cff.IndexData; -import org.apache.fontbox.cff.Type2CharStringParser; import org.apache.fop.fonts.cff.CFFDataReader; import org.apache.fop.fonts.cff.CFFDataReader.CFFIndexData; import org.apache.fop.fonts.cff.CFFDataReader.DICTEntry; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.apache.fop.fonts.truetype.OTFSubSetFile.BytesNumber; public class OTFSubSetFileTestCase extends OTFFileTestCase { @@ -47,10 +46,6 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { private byte[] sourceSansData; CFFDataReader cffReaderHeitiStd; - public OTFSubSetFileTestCase() throws IOException { - super(); - } - /** * Initialises the test by creating the font subset. A CFFDataReader is * also created based on the subset data for use in the tests. @@ -80,12 +75,17 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { public void testCharStringIndex() throws IOException { assertEquals(256, cffReaderSourceSans.getCharStringIndex().getNumObjects()); assertTrue(checkCorrectOffsets(cffReaderSourceSans.getCharStringIndex())); - validateCharStrings(cffReaderSourceSans); + validateCharStrings(cffReaderSourceSans, sourceSansSubset.getCFFReader()); } + /** + * Checks the index data to ensure that the offsets are valid + * @param indexData The index data to check + * @return Returns true if it is found to be valid + */ private boolean checkCorrectOffsets(CFFIndexData indexData) { int last = 0; - for (int i = 0;i < indexData.getOffsets().length;i++) { + for (int i = 0; i < indexData.getOffsets().length; i++) { if (indexData.getOffsets()[i] < last) { return false; } @@ -94,35 +94,268 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { return true; } - private void validateCharStrings(CFFDataReader cffReader) throws IOException { + /** + * Validates the subset font CharString data by comparing it with the original. + * @param subsetCFF The subset CFFDataReader containing the CharString data + * @param origCFF The original CFFDataReader containing the CharString data + * @throws IOException + */ + private void validateCharStrings(CFFDataReader subsetCFF, CFFDataReader origCFF) + throws IOException { CFFFont sourceSansOriginal = sourceSansProBold.fileFont; + CFFIndexData charStrings = subsetCFF.getCharStringIndex(); Map<String, byte[]> origCharStringData = sourceSansOriginal.getCharStringsDict(); - IndexData origGlobalIndex = sourceSansOriginal.getGlobalSubrIndex(); - IndexData origLocalIndex = sourceSansOriginal.getLocalSubrIndex(); + for (int i = 0; i < charStrings.getNumObjects(); i++) { + byte[] origCharData = origCharStringData.get(origCharStringData.keySet().toArray( + new String[0])[i]); + byte[] charData = charStrings.getValue(i); + List<BytesNumber> origOperands = getFullCharString(origCharData, origCFF); + List<BytesNumber> subsetOperands = getFullCharString(charData, subsetCFF); + for (int j = 0; j < origOperands.size(); j++) { + assertTrue(origOperands.get(j).equals(subsetOperands.get(j))); + } + } + } + + /** + * Recursively reads and constructs the full CharString for comparison + * @param data The original byte data of the CharString + * @param cffData The CFFDataReader containing the subroutine indexes + * @return Returns a list of parsed operands and operators + * @throws IOException + */ + private List<BytesNumber> getFullCharString(byte[] data, CFFDataReader cffData) throws IOException { + CFFIndexData localIndexSubr = cffData.getLocalIndexSubr(); + CFFIndexData globalIndexSubr = cffData.getGlobalIndexSubr(); + boolean hasLocalSubroutines = localIndexSubr != null && localIndexSubr.getNumObjects() > 0; + boolean hasGlobalSubroutines = globalIndexSubr != null && globalIndexSubr.getNumObjects() > 0; + ArrayList<BytesNumber> operands = new ArrayList<BytesNumber>(); + for (int dataPos = 0; dataPos < data.length; dataPos++) { + int b0 = data[dataPos] & 0xff; + if (b0 == 10 && hasLocalSubroutines) { + int subrNumber = getSubrNumber(localIndexSubr.getNumObjects(), + operands.get(operands.size() - 1).getNumber()); + byte[] subr = localIndexSubr.getValue(subrNumber); + List<BytesNumber> subrOperands = getFullCharString(subr, cffData); + operands = mergeOperands(operands, subrOperands); + } else if (b0 == 29 && hasGlobalSubroutines) { + int subrNumber = getSubrNumber(globalIndexSubr.getNumObjects(), + operands.get(operands.size() - 1).getNumber()); + byte[] subr = globalIndexSubr.getValue(subrNumber); + ArrayList<BytesNumber> subrOperands = (ArrayList<BytesNumber>)getFullCharString(subr, cffData); + operands = mergeOperands(operands, subrOperands); + } else if ((b0 >= 0 && b0 <= 27) || (b0 >= 29 && b0 <= 31)) { + int size = 1; + int b1 = -1; + if (b0 == 12) { + b1 = data[dataPos++] & 0xff; + size = 2; + } + if (b0 == 19 || b0 == 20) { + dataPos += 1; + size = 2; + } + operands.add(new Operator(b0, size, getOperatorName(b0, b1))); + } else if (b0 == 28 || (b0 >= 32 && b0 <= 255)) { + operands.add(readNumber(b0, data, dataPos)); + dataPos += operands.get(operands.size() - 1).getNumBytes() - 1; + } + } + return operands; + } + + /** + * Merges two lists of operands. This is typically used to merge the CharString + * data with that of a parsed and referenced subroutine. + * @param charString The parsed CharString data so far + * @param subroutine The parsed elements from a subroutine + * @return Returns a merged list of both CharString and subroutine elements. + */ + private ArrayList<BytesNumber> mergeOperands(List<BytesNumber> charString, + List<BytesNumber> subroutine) { + BytesNumber[] charStringOperands = charString.toArray(new BytesNumber[0]); + BytesNumber[] subroutineOperands = subroutine.toArray(new BytesNumber[0]); + BytesNumber[] mergeData = new BytesNumber[charStringOperands.length - 1 + + subroutineOperands.length - 1]; + System.arraycopy(charStringOperands, 0, mergeData, 0, charStringOperands.length - 1); + System.arraycopy(subroutineOperands, 0, mergeData, charStringOperands.length - 1, + subroutineOperands.length - 1); + ArrayList<BytesNumber> hello = new ArrayList<BytesNumber>(); + hello.addAll(Arrays.asList(mergeData)); + return hello; + } - CFFDataInput globalSubrs = new CFFDataInput(cffReader.getGlobalIndexSubr().getByteData()); - CFFDataInput localSubrs = new CFFDataInput(cffReader.getLocalIndexSubr().getByteData()); + /** + * Parses a number from one or more bytes + * @param b0 The first byte to identify how to interpret the number + * @param input The original byte data containing the number + * @param curPos The current position of the number + * @return Returns the number + * @throws IOException + */ + private BytesNumber readNumber(int b0, byte[] input, int curPos) throws IOException { + if (b0 == 28) { + int b1 = input[curPos + 1] & 0xff; + int b2 = input[curPos + 2] & 0xff; + return new BytesNumber(Integer.valueOf((short) (b1 << 8 | b2)), 3); + } else if (b0 >= 32 && b0 <= 246) { + return new BytesNumber(Integer.valueOf(b0 - 139), 1); + } else if (b0 >= 247 && b0 <= 250) { + int b1 = input[curPos + 1] & 0xff; + return new BytesNumber(Integer.valueOf((b0 - 247) * 256 + b1 + 108), 2); + } else if (b0 >= 251 && b0 <= 254) { + int b1 = input[curPos + 1] & 0xff; + return new BytesNumber(Integer.valueOf(-(b0 - 251) * 256 - b1 - 108), 2); + } else if (b0 == 255) { + int b1 = input[curPos + 1] & 0xff; + int b2 = input[curPos + 2] & 0xff; + return new BytesNumber(Integer.valueOf((short)(b1 << 8 | b2)), 5); + } else { + throw new IllegalArgumentException(); + } + } - IndexData globalIndexData = CFFParser.readIndexData(globalSubrs); - IndexData localIndexData = CFFParser.readIndexData(localSubrs); + /** + * Gets the subroutine number according to the number of subroutines + * and the provided operand. + * @param numSubroutines The number of subroutines used to calculate the + * subroutine reference. + * @param operand The operand for the subroutine + * @return Returns the calculated subroutine number + */ + private int getSubrNumber(int numSubroutines, int operand) { + int bias = getBias(numSubroutines); + return bias + operand; + } - CFFIndexData charStrings = cffReader.getCharStringIndex(); - for (int i = 0;i < charStrings.getNumObjects();i++) { - byte[] charData = charStrings.getValue(i); - Type2CharStringParser parser = new Type2CharStringParser(); + /** + * Gets the bias give the number of subroutines. This is used in the + * calculation to determine a subroutine's number + * @param subrCount The number of subroutines for a given index + * @return Returns the bias value + */ + private int getBias(int subrCount) { + if (subrCount < 1240) { + return 107; + } else if (subrCount < 33900) { + return 1131; + } else { + return 32768; + } + } - byte[] origCharData = origCharStringData.get(origCharStringData.keySet().toArray( - new String[0])[i]); - List<Object> origSeq = parser.parse(origCharData, origGlobalIndex, origLocalIndex); + /** + * A class representing an operator from the CharString data + */ + private class Operator extends BytesNumber { + private String opName = ""; - List<Object> subsetSeq = parser.parse(charData, globalIndexData, localIndexData); + public Operator(int number, int numBytes, String opName) { + super(number, numBytes); + this.opName = opName; + } + public String toString() { + return String.format("[%s]", opName); + } + } - //Validates the subset glyph render routines against the originals - assertEquals(origSeq, subsetSeq); + /** + * Gets the identifying name for the given operator. This is primarily + * used for debugging purposes. See the Type 2 CharString Format specification + * document (Technical Note #5177) Appendix A (Command Codes). + * @param operator The operator code + * @param codeb The second byte of the operator + * @return Returns the operator name. + */ + private String getOperatorName(int operator, int operatorB) { + switch (operator) { + case 0: return "Reserved"; + case 1: return "hstem"; + case 2: return "Reserved"; + case 3: return "vstem"; + case 4: return "vmoveto"; + case 5: return "rlineto"; + case 6: return "hlineto"; + case 7: return "vlineto"; + case 8: return "rrcurveto"; + case 9: return "Reserved"; + case 10: return "callsubr"; + case 11: return "return"; + case 12: return getDoubleOpName(operatorB); + case 13: return "Reserved"; + case 14: return "enchar"; + case 15: + case 16: + case 17: return "Reserved"; + case 18: return "hstemhm"; + case 19: return "hintmask"; + case 20: return "cntrmask"; + case 21: return "rmoveto"; + case 22: return "hmoveto"; + case 23: return "vstemhm"; + case 24: return "rcurveline"; + case 25: return "rlinecurve"; + case 26: return "vvcurveto"; + case 27: return "hhcurveto"; + case 28: return "shortint"; + case 29: return "callgsubr"; + case 30: return "vhcurveto"; + case 31: return "hvcurveto"; + default: return "Unknown"; } } /** + * Gets the name of a double byte operator code + * @param operator The second byte of the operator + * @return Returns the name + */ + private String getDoubleOpName(int operator) { + switch (operator) { + case 0: + case 1: + case 2: return "Reserved"; + case 3: return "and"; + case 4: return "or"; + case 5: return "not"; + case 6: + case 7: + case 8: return "Reserved"; + case 9: return "abs"; + case 10: return "add"; + case 11: return "sub"; + case 12: return "div"; + case 13: return "Reserved"; + case 14: return "neg"; + case 15: return "eq"; + case 16: + case 17: return "Reserved"; + case 18: return "drop"; + case 19: return "Reserved"; + case 20: return "put"; + case 21: return "get"; + case 22: return "ifelse"; + case 23: return "random"; + case 24: return "mul"; + case 25: return "Reserved"; + case 26: return "sqrt"; + case 27: return "dup"; + case 28: return "exch"; + case 29: return "index"; + case 30: return "roll"; + case 31: + case 32: + case 33: return "Reserved"; + case 34: return "hflex"; + case 35: return "flex"; + case 36: return "hflex1"; + case 37: return "flex1"; + case 38: return "Reserved"; + default: return "Unknown"; + } + } + + /** * Validates the String index data and size * @throws IOException */ diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java index a390bef0f..a78b3e674 100644 --- a/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java +++ b/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java @@ -26,12 +26,12 @@ import java.util.Map; import org.junit.Test; -import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion; + /** * Class for testing org.apache.fop.fonts.truetype.TTFFile */ @@ -430,6 +430,24 @@ public class TTFFileTestCase { assertEquals(true, droidmonoTTFFile.isEmbeddable()); } + /** Underline position and thickness. */ + @Test + public void testUnderline() { + assertEquals(-63, dejavuTTFFile.getUnderlinePosition()); + assertEquals(43, dejavuTTFFile.getUnderlineThickness()); + assertEquals(-75, droidmonoTTFFile.getUnderlinePosition()); + assertEquals(49, droidmonoTTFFile.getUnderlineThickness()); + } + + /** Strikeout position and thickness. */ + @Test + public void testStrikeout() { + assertEquals(258, dejavuTTFFile.getStrikeoutPosition()); + assertEquals(49, dejavuTTFFile.getStrikeoutThickness()); + assertEquals(243, droidmonoTTFFile.getStrikeoutPosition()); + assertEquals(49, droidmonoTTFFile.getStrikeoutThickness()); + } + /** * Test readFont() - Add implementation if necessary. */ diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java index f50b116ac..899fe1d73 100644 --- a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java +++ b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java @@ -25,14 +25,14 @@ import java.net.URI; import org.junit.Test; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import org.apache.fop.apps.io.InternalResourceResolver; import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.fonts.EmbeddingMode; import org.apache.fop.fonts.EncodingMode; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - /** * Test case for {@link OFFontLoader}. */ diff --git a/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java b/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java index 93443a0d9..31a613567 100644 --- a/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java +++ b/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java @@ -19,9 +19,6 @@ package org.apache.fop.fonts.type1; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.awt.Rectangle; import java.io.IOException; import java.io.InputStream; @@ -29,6 +26,9 @@ import java.util.List; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + /** * Test case for {@link AFMParser}. */ @@ -128,4 +128,13 @@ public class AFMParserTestCase { private boolean objectEquals(Object o1, Object o2) { return o1 == null ? o2 == null : (o1 == o2 || o1.equals(o2)); } + + @Test + public void testUnderlinePositionAndThickness() throws IOException { + AFMFile afm = sut.parse(getClass().getResourceAsStream("underline.afm"), null); + AFMWritingDirectionMetrics metrics = afm.getWritingDirectionMetrics(0); + assertEquals(-96, metrics.getUnderlinePosition()); + assertEquals(58, metrics.getUnderlineThickness()); + } + } diff --git a/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java b/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java index 10ba42119..a3a3e1c40 100644 --- a/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java +++ b/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java @@ -19,8 +19,6 @@ package org.apache.fop.fonts.type1; -import static org.junit.Assert.assertEquals; - import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; @@ -30,6 +28,8 @@ import java.io.InputStreamReader; import org.junit.BeforeClass; import org.junit.Test; +import static org.junit.Assert.assertEquals; + /** * Test case for {@link AdobeStandardEncoding}. */ diff --git a/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java b/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java index de9af2d33..c3e9334dd 100644 --- a/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java +++ b/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java @@ -19,10 +19,6 @@ package org.apache.fop.fonts.type1; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import java.awt.Rectangle; import java.io.IOException; import java.util.HashMap; @@ -31,6 +27,10 @@ import java.util.Stack; import org.junit.Test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import org.apache.fop.fonts.NamedCharacter; import org.apache.fop.fonts.type1.AFMParser.ValueHandler; diff --git a/test/java/org/apache/fop/fonts/type1/underline.afm b/test/java/org/apache/fop/fonts/type1/underline.afm new file mode 100644 index 000000000..8137b41eb --- /dev/null +++ b/test/java/org/apache/fop/fonts/type1/underline.afm @@ -0,0 +1,4 @@ +StartFontMetrics 2.0 +UnderlinePosition -96 +UnderlineThickness 58 +EndFontMetrics diff --git a/test/java/org/apache/fop/fotreetest/ext/AssertElement.java b/test/java/org/apache/fop/fotreetest/ext/AssertElement.java index 5070984d1..955644ae4 100644 --- a/test/java/org/apache/fop/fotreetest/ext/AssertElement.java +++ b/test/java/org/apache/fop/fotreetest/ext/AssertElement.java @@ -20,6 +20,9 @@ package org.apache.fop.fotreetest.ext; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; + import org.apache.fop.apps.FOPException; import org.apache.fop.fo.FONode; import org.apache.fop.fo.FOPropertyMapping; @@ -32,9 +35,6 @@ import org.apache.fop.fo.properties.Property; import org.apache.fop.fo.properties.SpaceProperty; import org.apache.fop.fotreetest.ResultCollector; -import org.xml.sax.Attributes; -import org.xml.sax.Locator; - /** * Defines the assert element for the FOP Test extension. */ diff --git a/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java b/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java index eee0efac4..b61944eae 100644 --- a/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java +++ b/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java @@ -19,8 +19,8 @@ package org.apache.fop.fotreetest.ext; -import org.apache.fop.fo.FONode; import org.apache.fop.fo.ElementMapping; +import org.apache.fop.fo.FONode; /** * This class provides the element mapping for FOP. diff --git a/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java b/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java index f4763512a..7f3036c24 100644 --- a/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java +++ b/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java @@ -19,10 +19,6 @@ package org.apache.fop.image.loader.batik; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.File; @@ -30,6 +26,10 @@ import java.io.File; import org.junit.Ignore; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; diff --git a/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java b/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java index efc5df1f7..3d690b67c 100644 --- a/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java +++ b/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java @@ -19,15 +19,15 @@ package org.apache.fop.image.loader.batik; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - import java.io.File; import java.io.IOException; import org.junit.Ignore; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageManager; diff --git a/test/java/org/apache/fop/intermediate/AbstractIFTest.java b/test/java/org/apache/fop/intermediate/AbstractIFTest.java index 419db2c47..48c3f335b 100644 --- a/test/java/org/apache/fop/intermediate/AbstractIFTest.java +++ b/test/java/org/apache/fop/intermediate/AbstractIFTest.java @@ -34,7 +34,6 @@ import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.w3c.dom.Document; - import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; diff --git a/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java b/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java index 3fc855cef..2003958c8 100644 --- a/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java +++ b/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java @@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses; * JUnit test suite for the area tree XML format */ @RunWith(Suite.class) -@SuiteClasses({ AreaTreeParserTestCase.class }) +@SuiteClasses(AreaTreeParserTestCase.class) public class AreaTreeXMLFormatTestSuite { } diff --git a/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java b/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java index 58281fc10..83dd88661 100644 --- a/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java +++ b/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java @@ -19,8 +19,6 @@ package org.apache.fop.intermediate; -import static org.junit.Assert.fail; - import java.io.File; import javax.xml.transform.ErrorListener; @@ -34,6 +32,8 @@ import javax.xml.transform.stream.StreamSource; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.fail; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; diff --git a/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java b/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java index f960990b2..71b26cb9b 100644 --- a/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java +++ b/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java @@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses; * A test suite for testing the Intermediate Format output. */ @RunWith(Suite.class) -@SuiteClasses({ IFTestCase.class }) +@SuiteClasses(IFTestCase.class) public final class IntermediateFormatTestSuite { } diff --git a/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java b/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java index 5d87df1a5..ea60f2ff4 100644 --- a/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java +++ b/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java @@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses; * JUnit test suite for the intermediate format */ @RunWith(Suite.class) -@SuiteClasses({ IFParserTestCase.class }) +@SuiteClasses(IFParserTestCase.class) public final class LayoutIFTestSuite { } diff --git a/test/java/org/apache/fop/layoutengine/ElementListCheck.java b/test/java/org/apache/fop/layoutengine/ElementListCheck.java index e63fc3291..4d33d670b 100644 --- a/test/java/org/apache/fop/layoutengine/ElementListCheck.java +++ b/test/java/org/apache/fop/layoutengine/ElementListCheck.java @@ -22,16 +22,17 @@ package org.apache.fop.layoutengine; import java.util.Iterator; import java.util.List; -import org.apache.fop.layoutmgr.KnuthBox; -import org.apache.fop.layoutmgr.KnuthElement; -import org.apache.fop.layoutmgr.KnuthGlue; -import org.apache.fop.layoutmgr.KnuthPenalty; import org.w3c.dom.CDATASection; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; +import org.apache.fop.layoutmgr.KnuthBox; +import org.apache.fop.layoutmgr.KnuthElement; +import org.apache.fop.layoutmgr.KnuthGlue; +import org.apache.fop.layoutmgr.KnuthPenalty; + /** * Check implementation that checks a Knuth element list. */ diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java index e739221b0..ad0804af5 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java @@ -21,8 +21,12 @@ package org.apache.fop.layoutengine; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; @@ -41,10 +45,16 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import org.apache.fop.DebugHelper; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; @@ -53,6 +63,8 @@ import org.apache.fop.apps.FormattingResults; import org.apache.fop.area.AreaTreeModel; import org.apache.fop.area.AreaTreeParser; import org.apache.fop.area.RenderPagesModel; +import org.apache.fop.events.Event; +import org.apache.fop.events.EventListener; import org.apache.fop.events.model.EventSeverity; import org.apache.fop.fonts.FontInfo; import org.apache.fop.intermediate.IFTester; @@ -131,6 +143,8 @@ public class LayoutEngineTestCase { Fop fop; FopFactory effFactory; + EventsChecker eventsChecker = new EventsChecker( + new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); try { Document testDoc = testAssistant.loadTestCase(testFile); effFactory = testAssistant.getFopFactory(testDoc); @@ -146,8 +160,7 @@ public class LayoutEngineTestCase { //Setup FOP for area tree rendering FOUserAgent ua = effFactory.newFOUserAgent(); - ua.getEventBroadcaster().addEventListener( - new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); + ua.getEventBroadcaster().addEventListener(eventsChecker); XMLRenderer atrenderer = new XMLRenderer(ua); atrenderer.setContentHandler(athandler); @@ -167,7 +180,60 @@ public class LayoutEngineTestCase { } FormattingResults results = fop.getResults(); LayoutResult result = new LayoutResult(doc, elCollector, results); - checkAll(effFactory, testFile, result); + checkAll(effFactory, testFile, result, eventsChecker); + } + + private static class EventsChecker implements EventListener { + + private final List<Event> events = new ArrayList<Event>(); + + private final EventListener defaultListener; + + /** + * @param fallbackListener the listener to which this class will pass through + * events that are not being checked + */ + public EventsChecker(EventListener fallbackListener) { + this.defaultListener = fallbackListener; + } + + public void processEvent(Event event) { + events.add(event); + } + + public void checkEvent(String expectedKey, Map<String, String> expectedParams) { + boolean eventFound = false; + for (Iterator<Event> iter = events.iterator(); !eventFound && iter.hasNext();) { + Event event = iter.next(); + if (event.getEventKey().equals(expectedKey)) { + eventFound = true; + iter.remove(); + checkParameters(event, expectedParams); + } + } + if (!eventFound) { + fail("Event did not occur but was expected to: " + expectedKey + expectedParams); + } + } + + private void checkParameters(Event event, Map<String, String> expectedParams) { + Map<String, Object> actualParams = event.getParams(); + for (Map.Entry<String, String> expectedParam : expectedParams.entrySet()) { + assertTrue("Event \"" + event.getEventKey() + + "\" is missing parameter \"" + expectedParam.getKey() + '"', + actualParams.containsKey(expectedParam.getKey())); + assertEquals("Event \"" + event.getEventKey() + + "\" has wrong value for parameter \"" + expectedParam.getKey() + "\";", + actualParams.get(expectedParam.getKey()).toString(), + expectedParam.getValue()); + } + } + + public void emitUncheckedEvents() { + for (Event event : events) { + defaultListener.processEvent(event); + } + } } /** @@ -177,8 +243,8 @@ public class LayoutEngineTestCase { * @param result The layout results * @throws TransformerException if a problem occurs in XSLT/JAXP */ - protected void checkAll(FopFactory fopFactory, File testFile, LayoutResult result) - throws TransformerException { + protected void checkAll(FopFactory fopFactory, File testFile, LayoutResult result, + EventsChecker eventsChecker) throws TransformerException { Element testRoot = testAssistant.getTestRoot(testFile); NodeList nodes; @@ -196,6 +262,13 @@ public class LayoutEngineTestCase { Document ifDocument = createIF(fopFactory, testFile, result.getAreaTree()); ifTester.doIFChecks(testFile.getName(), ifChecks, ifDocument); } + + nodes = testRoot.getElementsByTagName("event-checks"); + if (nodes.getLength() > 0) { + Element eventChecks = (Element) nodes.item(0); + doEventChecks(eventChecks, eventsChecker); + } + eventsChecker.emitUncheckedEvents(); } private Document createIF(FopFactory fopFactory, File testFile, Document areaTreeXML) @@ -254,4 +327,28 @@ public class LayoutEngineTestCase { } } + private void doEventChecks(Element eventChecks, EventsChecker eventsChecker) { + NodeList events = eventChecks.getElementsByTagName("event"); + for (int i = 0; i < events.getLength(); i++) { + Element event = (Element) events.item(i); + NamedNodeMap attributes = event.getAttributes(); + Map<String, String> params = new HashMap<String, String>(); + String key = null; + for (int j = 0; j < attributes.getLength(); j++) { + Node attribute = attributes.item(j); + String name = attribute.getNodeName(); + String value = attribute.getNodeValue(); + if ("key".equals(name)) { + key = value; + } else { + params.put(name, value); + } + } + if (key == null) { + throw new RuntimeException("An event element must have a \"key\" attribute"); + } + eventsChecker.checkEvent(key, params); + } + } + } diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java index 2a70f255d..89bf28a55 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java @@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses; * JUnit test suit for running layout engine test under JUnit control. */ @RunWith(Suite.class) -@SuiteClasses({ LayoutEngineTestCase.class }) +@SuiteClasses(LayoutEngineTestCase.class) public class LayoutEngineTestSuite { } diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java index fb7f07023..963b66dff 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java @@ -162,7 +162,7 @@ public final class LayoutEngineTestUtils { Collection<File[]> parametersForJUnit4 = new ArrayList<File[]>(); int index = 0; for (File f : files) { - parametersForJUnit4.add(new File[] { f }); + parametersForJUnit4.add(new File[] {f}); if (DEBUG) { System.out.println(String.format("%3d %s", index++, f)); } diff --git a/test/java/org/apache/fop/layoutengine/LayoutResult.java b/test/java/org/apache/fop/layoutengine/LayoutResult.java index 52c83daa8..92c459234 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutResult.java +++ b/test/java/org/apache/fop/layoutengine/LayoutResult.java @@ -19,9 +19,10 @@ package org.apache.fop.layoutengine; -import org.apache.fop.apps.FormattingResults; import org.w3c.dom.Document; +import org.apache.fop.apps.FormattingResults; + /** * This class holds references to all the results from the FOP processing run. */ diff --git a/test/java/org/apache/fop/layoutmgr/table/TableCellLayoutManagerTestCase.java b/test/java/org/apache/fop/layoutmgr/table/TableCellLayoutManagerTestCase.java index c2fc84551..629e5f1c6 100644 --- a/test/java/org/apache/fop/layoutmgr/table/TableCellLayoutManagerTestCase.java +++ b/test/java/org/apache/fop/layoutmgr/table/TableCellLayoutManagerTestCase.java @@ -23,6 +23,10 @@ import java.awt.Color; import org.junit.Test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableCell; @@ -37,10 +41,6 @@ import org.apache.fop.layoutmgr.PageSequenceLayoutManager; import org.apache.fop.layoutmgr.PositionIterator; import org.apache.fop.layoutmgr.RetrieveTableMarkerLayoutManager; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - public class TableCellLayoutManagerTestCase { // this test aims to check that the first call to addAreas() calls diff --git a/test/java/org/apache/fop/logging/LoggingElementListObserver.java b/test/java/org/apache/fop/logging/LoggingElementListObserver.java index 26c4db00e..7824a6b8b 100644 --- a/test/java/org/apache/fop/logging/LoggingElementListObserver.java +++ b/test/java/org/apache/fop/logging/LoggingElementListObserver.java @@ -24,9 +24,10 @@ import java.util.ListIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + +import org.apache.fop.layoutmgr.ElementListObserver.Observer; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.ListElement; -import org.apache.fop.layoutmgr.ElementListObserver.Observer; /** * <p>Logs all observed element lists. diff --git a/test/java/org/apache/fop/memory/MemoryEater.java b/test/java/org/apache/fop/memory/MemoryEater.java index 7afb80476..efe0cc489 100644 --- a/test/java/org/apache/fop/memory/MemoryEater.java +++ b/test/java/org/apache/fop/memory/MemoryEater.java @@ -45,7 +45,7 @@ import org.apache.fop.apps.MimeConstants; /** * Debug tool to create and process large FO files by replicating them a specified number of times. */ -public class MemoryEater { +public final class MemoryEater { private SAXTransformerFactory tFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); @@ -53,7 +53,7 @@ public class MemoryEater { private Stats stats; - public MemoryEater() throws TransformerConfigurationException, MalformedURLException { + private MemoryEater() throws TransformerConfigurationException, MalformedURLException { File xsltFile = new File("test/xsl/fo-replicator.xsl"); Source xslt = new StreamSource(xsltFile); replicatorTemplates = tFactory.newTemplates(xslt); diff --git a/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java b/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java index 95d5c0a1d..dec62c0a4 100644 --- a/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java +++ b/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java @@ -23,10 +23,11 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; + /** * Test case for {@link AbstractPDFStream}. */ diff --git a/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java b/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java index a9d7bf4f6..3301fff9e 100644 --- a/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java +++ b/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java @@ -19,10 +19,6 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -33,6 +29,10 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + /** * Tests the {@link FileIDGenerator} class. */ @@ -96,7 +96,7 @@ public class FileIDGeneratorTestCase { assertTrue(Arrays.equals(originalFileID, updatedFileID)); } - private static interface TestGetter { + private interface TestGetter { FileIDGenerator getSut() throws Exception; } diff --git a/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java b/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java index 89d980029..21eb6088f 100644 --- a/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java +++ b/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java @@ -19,15 +19,15 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.io.IOException; import java.io.OutputStream; import java.util.List; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import org.apache.fop.pdf.xref.CompressedObjectReference; public class ObjectStreamManagerTestCase { diff --git a/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java b/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java index 317828e4b..3512e1147 100644 --- a/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java +++ b/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java @@ -19,8 +19,6 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; @@ -29,6 +27,8 @@ import java.util.List; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class ObjectStreamTestCase { private static final String OBJECT_CONTENT = "<<\n /Foo True\n /Bar False\n>>\n"; diff --git a/test/java/org/apache/fop/pdf/PDFAModeTestCase.java b/test/java/org/apache/fop/pdf/PDFAModeTestCase.java index 352e0710e..68609575a 100644 --- a/test/java/org/apache/fop/pdf/PDFAModeTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFAModeTestCase.java @@ -97,7 +97,7 @@ public class PDFAModeTestCase { } @Test - public void checkPDFA_1a() { + public void checkPDFA1a() { new PDFAModeChecker(PDFAMode.PDFA_1A) .isEnabled() .isPart1() @@ -106,7 +106,7 @@ public class PDFAModeTestCase { } @Test - public void checkPDFA_1b() { + public void checkPDFA1b() { new PDFAModeChecker(PDFAMode.PDFA_1B) .isEnabled() .isPart1() @@ -115,7 +115,7 @@ public class PDFAModeTestCase { } @Test - public void checkPDFA_2a() { + public void checkPDFA2a() { new PDFAModeChecker(PDFAMode.PDFA_2A) .isEnabled() .isNotPart1() @@ -124,7 +124,7 @@ public class PDFAModeTestCase { } @Test - public void checkPDFA_2b() { + public void checkPDFA2b() { new PDFAModeChecker(PDFAMode.PDFA_2B) .isEnabled() .isNotPart1() @@ -133,7 +133,7 @@ public class PDFAModeTestCase { } @Test - public void checkPDFA_2u() { + public void checkPDFA2u() { new PDFAModeChecker(PDFAMode.PDFA_2U) .isEnabled() .isNotPart1() diff --git a/test/java/org/apache/fop/pdf/PDFArrayTestCase.java b/test/java/org/apache/fop/pdf/PDFArrayTestCase.java index 418b2f1a9..53e9bdba0 100644 --- a/test/java/org/apache/fop/pdf/PDFArrayTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFArrayTestCase.java @@ -19,17 +19,17 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import org.junit.Before; import org.junit.Test; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * Test case for {@link PDFArray}. diff --git a/test/java/org/apache/fop/pdf/PDFDestsTestCase.java b/test/java/org/apache/fop/pdf/PDFDestsTestCase.java index 49c1e6dab..4655b258d 100644 --- a/test/java/org/apache/fop/pdf/PDFDestsTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFDestsTestCase.java @@ -19,13 +19,13 @@ package org.apache.fop.pdf; -import org.junit.Before; -import org.junit.Test; - import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.junit.Before; +import org.junit.Test; + /** * Test case for {@link PDFDests}. */ diff --git a/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java b/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java index 00224e93e..267e05c2c 100644 --- a/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java @@ -19,17 +19,18 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - import java.io.ByteArrayOutputStream; import java.io.IOException; -import org.apache.commons.io.output.CountingOutputStream; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import org.apache.commons.io.output.CountingOutputStream; + /** * Test case for {@link PDFDictionary}. diff --git a/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java b/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java index c7eff506e..880613a78 100644 --- a/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java @@ -24,8 +24,6 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics2D; -import junit.framework.Assert; - import org.junit.Test; import org.apache.commons.io.output.ByteArrayOutputStream; @@ -34,6 +32,8 @@ import org.apache.xmlgraphics.util.UnitConv; import org.apache.fop.svg.PDFDocumentGraphics2D; +import junit.framework.Assert; + /** * Tests for {@link PDFDocumentGraphics2D}. */ diff --git a/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java b/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java index 8965635b9..e58201f13 100644 --- a/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java @@ -19,12 +19,12 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import org.junit.Test; -import java.io.ByteArrayOutputStream; -import java.io.IOException; +import static org.junit.Assert.assertEquals; /** * Test case for {@link PDFDocument} diff --git a/test/java/org/apache/fop/pdf/PDFEncodingTestCase.java b/test/java/org/apache/fop/pdf/PDFEncodingTestCase.java index 34e48f1a6..2f80b077c 100644 --- a/test/java/org/apache/fop/pdf/PDFEncodingTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFEncodingTestCase.java @@ -19,11 +19,11 @@ package org.apache.fop.pdf; import org.junit.Test; -import org.apache.fop.fonts.CodePointMapping; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import org.apache.fop.fonts.CodePointMapping; + public class PDFEncodingTestCase { /** diff --git a/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java b/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java index ea3b011c7..e3f8344e0 100644 --- a/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java +++ b/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java @@ -19,10 +19,6 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -43,6 +39,10 @@ import javax.crypto.spec.SecretKeySpec; import org.junit.Test; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + /** * Tests the {@link PDFEncryptionJCE} class. */ diff --git a/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java b/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java index 5e4b9e2e4..edbc7e449 100644 --- a/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java @@ -53,7 +53,7 @@ public class PDFFactoryTestCase { @Override public int[] getWidths() { - return new int[] { 0 }; + return new int[] {0}; } @Override diff --git a/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java b/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java index 2504d871a..d1cc6273d 100644 --- a/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java @@ -19,10 +19,10 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertFalse; - import org.junit.Test; +import static org.junit.Assert.assertFalse; + public class PDFFilterListTestCase { @Test diff --git a/test/java/org/apache/fop/pdf/PDFNameTestCase.java b/test/java/org/apache/fop/pdf/PDFNameTestCase.java index 80917f416..8d7321496 100644 --- a/test/java/org/apache/fop/pdf/PDFNameTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFNameTestCase.java @@ -22,11 +22,13 @@ package org.apache.fop.pdf; import java.io.ByteArrayOutputStream; import java.io.IOException; -import org.apache.commons.io.output.CountingOutputStream; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.fail; + import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.apache.commons.io.output.CountingOutputStream; /** * Test class for {@link PDFName}. diff --git a/test/java/org/apache/fop/pdf/PDFNullTestCase.java b/test/java/org/apache/fop/pdf/PDFNullTestCase.java index 98427cd20..87dacc7f6 100644 --- a/test/java/org/apache/fop/pdf/PDFNullTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFNullTestCase.java @@ -19,12 +19,12 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import org.junit.Test; -import java.io.ByteArrayOutputStream; -import java.io.IOException; +import static org.junit.Assert.assertEquals; /** * Test case for {@link PDFNull}. diff --git a/test/java/org/apache/fop/pdf/PDFNumberTestCase.java b/test/java/org/apache/fop/pdf/PDFNumberTestCase.java index ed660af8d..65f484dc7 100644 --- a/test/java/org/apache/fop/pdf/PDFNumberTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFNumberTestCase.java @@ -19,13 +19,13 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import java.io.IOException; import org.junit.Before; import org.junit.Test; -import java.io.IOException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; /** * This test tests PDFNumber's doubleOut() methods. diff --git a/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java b/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java index e0dca33bf..d36775cda 100644 --- a/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java @@ -19,11 +19,11 @@ package org.apache.fop.pdf; +import java.io.IOException; + import org.junit.Before; import org.junit.Test; -import java.io.IOException; - /** * Test case for {@link PDFNumsArray}. */ diff --git a/test/java/org/apache/fop/pdf/PDFObjectTestCase.java b/test/java/org/apache/fop/pdf/PDFObjectTestCase.java index 10ffa3b27..f35d2a15c 100644 --- a/test/java/org/apache/fop/pdf/PDFObjectTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFObjectTestCase.java @@ -19,17 +19,17 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.io.ByteArrayOutputStream; import java.io.IOException; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * Tests the PDFObject class. */ diff --git a/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java b/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java index 24b6a1c71..ed87cd23e 100644 --- a/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java @@ -19,14 +19,14 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + /** * Test case for {@link PDFRectangle}. */ diff --git a/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java b/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java index a2c6193cf..4e0e8814d 100644 --- a/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java @@ -19,12 +19,12 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import org.junit.Test; -import java.io.ByteArrayOutputStream; -import java.io.IOException; +import static org.junit.Assert.assertEquals; /** * Test case for {@link PDFReference}. diff --git a/test/java/org/apache/fop/pdf/PDFStreamTestCase.java b/test/java/org/apache/fop/pdf/PDFStreamTestCase.java index 20e38a600..b5fb66e00 100644 --- a/test/java/org/apache/fop/pdf/PDFStreamTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFStreamTestCase.java @@ -19,17 +19,17 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import java.io.ByteArrayOutputStream; import java.io.IOException; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + public class PDFStreamTestCase { private PDFStream stream; diff --git a/test/java/org/apache/fop/pdf/TableHeaderScopeTestCase.java b/test/java/org/apache/fop/pdf/TableHeaderScopeTestCase.java index a1d581402..2fa5008ed 100644 --- a/test/java/org/apache/fop/pdf/TableHeaderScopeTestCase.java +++ b/test/java/org/apache/fop/pdf/TableHeaderScopeTestCase.java @@ -109,14 +109,14 @@ public class TableHeaderScopeTestCase { } private PDFDictionary scopeAttribute(Scope scope) { - return argThat(new isScopeAttribute(scope)); + return argThat(new IsScopeAttribute(scope)); } - private static class isScopeAttribute extends ArgumentMatcher<PDFDictionary> { + private static class IsScopeAttribute extends ArgumentMatcher<PDFDictionary> { private final Scope expectedScope; - public isScopeAttribute(Scope expectedScope) { + public IsScopeAttribute(Scope expectedScope) { this.expectedScope = expectedScope; } diff --git a/test/java/org/apache/fop/pdf/VersionControllerTestCase.java b/test/java/org/apache/fop/pdf/VersionControllerTestCase.java index 74637c91f..e14fc9502 100644 --- a/test/java/org/apache/fop/pdf/VersionControllerTestCase.java +++ b/test/java/org/apache/fop/pdf/VersionControllerTestCase.java @@ -19,13 +19,13 @@ package org.apache.fop.pdf; +import org.junit.Before; +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; -import org.junit.Before; -import org.junit.Test; - /** * A test class for {@link VersionController}. diff --git a/test/java/org/apache/fop/pdf/VersionTestCase.java b/test/java/org/apache/fop/pdf/VersionTestCase.java index 9c90f0966..dd2731d8b 100644 --- a/test/java/org/apache/fop/pdf/VersionTestCase.java +++ b/test/java/org/apache/fop/pdf/VersionTestCase.java @@ -19,11 +19,11 @@ package org.apache.fop.pdf; +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.junit.Test; - /** * This is a test case for ({@link Version}. */ diff --git a/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java b/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java index 8b103d277..b7a326c64 100644 --- a/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java +++ b/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java @@ -19,14 +19,14 @@ package org.apache.fop.pdf.xref; -import static org.junit.Assert.assertArrayEquals; - import java.io.IOException; import java.util.Arrays; import java.util.List; import org.junit.Test; +import static org.junit.Assert.assertArrayEquals; + public class CompressedObjectReferenceTestCase extends ObjectReferenceTest { @Test diff --git a/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java b/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java index df1b86e53..cd55577cd 100644 --- a/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java +++ b/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java @@ -19,8 +19,6 @@ package org.apache.fop.pdf.xref; -import static org.junit.Assert.assertArrayEquals; - import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; @@ -32,6 +30,8 @@ import java.util.Map; import org.junit.Before; +import static org.junit.Assert.assertArrayEquals; + import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFInfo; import org.apache.fop.pdf.PDFPages; diff --git a/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java b/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java index b147084e8..a9f506aaa 100644 --- a/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java +++ b/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java @@ -19,8 +19,6 @@ package org.apache.fop.pdf.xref; -import static org.junit.Assert.assertArrayEquals; - import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -28,6 +26,8 @@ import java.util.List; import org.junit.Test; +import static org.junit.Assert.assertArrayEquals; + public class UncompressedObjectReferenceTestCase extends ObjectReferenceTest { @Test diff --git a/test/java/org/apache/fop/render/AbstractRenderingTest.java b/test/java/org/apache/fop/render/AbstractRenderingTest.java index 9d196e71d..297a9ba05 100644 --- a/test/java/org/apache/fop/render/AbstractRenderingTest.java +++ b/test/java/org/apache/fop/render/AbstractRenderingTest.java @@ -33,6 +33,7 @@ import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; + import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; diff --git a/test/java/org/apache/fop/render/RawPNGTestUtil.java b/test/java/org/apache/fop/render/RawPNGTestUtil.java index e6660bb42..506556c66 100644 --- a/test/java/org/apache/fop/render/RawPNGTestUtil.java +++ b/test/java/org/apache/fop/render/RawPNGTestUtil.java @@ -28,9 +28,9 @@ import org.apache.xmlgraphics.image.loader.ImageSize; public final class RawPNGTestUtil { - private static int NUM_ROWS = 32; - private static int NUM_COLUMNS = 32; - private static int DPI = 72; + private static final int NUM_ROWS = 32; + private static final int NUM_COLUMNS = 32; + private static final int DPI = 72; private RawPNGTestUtil() { @@ -83,7 +83,7 @@ public final class RawPNGTestUtil { } /** - * + * * @return a default ImageSize */ public static ImageSize getImageSize() { diff --git a/test/java/org/apache/fop/render/RendererFactoryTestCase.java b/test/java/org/apache/fop/render/RendererFactoryTestCase.java index 4bed835ec..1fa4ae0fa 100644 --- a/test/java/org/apache/fop/render/RendererFactoryTestCase.java +++ b/test/java/org/apache/fop/render/RendererFactoryTestCase.java @@ -19,13 +19,13 @@ package org.apache.fop.render; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.io.File; import org.junit.Test; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import org.apache.commons.io.output.NullOutputStream; import org.apache.fop.apps.FOPException; diff --git a/test/java/org/apache/fop/render/afp/AFPBorderPainterTestCase.java b/test/java/org/apache/fop/render/afp/AFPBorderPainterTestCase.java index 691d75f3f..dfe956d90 100644 --- a/test/java/org/apache/fop/render/afp/AFPBorderPainterTestCase.java +++ b/test/java/org/apache/fop/render/afp/AFPBorderPainterTestCase.java @@ -19,12 +19,15 @@ package org.apache.fop.render.afp; -import static org.junit.Assert.assertTrue; - import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.OutputStream; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + import org.apache.fop.afp.AFPBorderPainter; import org.apache.fop.afp.AFPLineDataInfo; import org.apache.fop.afp.AFPPaintingState; @@ -32,8 +35,6 @@ import org.apache.fop.afp.BorderPaintingInfo; import org.apache.fop.afp.DataStream; import org.apache.fop.afp.Factory; import org.apache.fop.fo.Constants; -import org.junit.Before; -import org.junit.Test; public class AFPBorderPainterTestCase { private ByteArrayOutputStream outStream; @@ -63,12 +64,12 @@ public class AFPBorderPainterTestCase { ds.endDocument(); assertTrue(line.getX1() == 4999 && line.getX2() == 8332); } - + class MyDataStream extends DataStream { public MyDataStream(Factory factory, AFPPaintingState paintingState, OutputStream outputStream) { super(factory, paintingState, outputStream); } - + public void createLine(AFPLineDataInfo lineDataInfo) { line = lineDataInfo; } diff --git a/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java index 799045872..8ed54049f 100644 --- a/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java +++ b/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java @@ -25,6 +25,10 @@ import java.util.Map; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + import org.apache.fop.afp.AFPConstants; import org.apache.fop.apps.AFPRendererConfBuilder; import org.apache.fop.apps.AbstractRendererConfigParserTester; @@ -33,9 +37,6 @@ import org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions; import static org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions.MODE_COLOR; import static org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions.MODE_GRAYSCALE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; public class AFPRendererConfigParserTestCase extends AbstractRendererConfigParserTester<AFPRendererConfBuilder, AFPRendererConfig> { diff --git a/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java index 115b3149a..48cf89240 100644 --- a/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java +++ b/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java @@ -24,6 +24,9 @@ import java.util.Map; import org.junit.Test; import org.mockito.ArgumentCaptor; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.verify; + import org.apache.fop.afp.AFPResourceLevel; import org.apache.fop.afp.AFPResourceLevel.ResourceType; import org.apache.fop.afp.AFPResourceLevelDefaults; @@ -33,9 +36,6 @@ import org.apache.fop.apps.MimeConstants; import org.apache.fop.render.afp.AFPRendererConfig.AFPRendererConfigParser; import org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.verify; - public class AFPRendererConfiguratorTestCase extends AbstractRendererConfiguratorTest<AFPRendererConfigurator, AFPRendererConfBuilder> { diff --git a/test/java/org/apache/fop/render/afp/NoOperationTestCase.java b/test/java/org/apache/fop/render/afp/NoOperationTestCase.java index 78578a2b6..9e83829f8 100644 --- a/test/java/org/apache/fop/render/afp/NoOperationTestCase.java +++ b/test/java/org/apache/fop/render/afp/NoOperationTestCase.java @@ -19,20 +19,22 @@ package org.apache.fop.render.afp; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import org.apache.commons.io.IOUtils; + import org.apache.fop.afp.AFPConstants; import org.apache.fop.afp.parser.MODCAParser; import org.apache.fop.afp.parser.UnparsedStructuredField; import org.apache.fop.apps.FOUserAgent; -import org.junit.Test; /** * Tests generation of afp:no-operation (NOPs). diff --git a/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfigParserTester.java b/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfigParserTester.java index 04f872a84..cae184d51 100644 --- a/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfigParserTester.java +++ b/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfigParserTester.java @@ -24,6 +24,11 @@ import java.awt.image.BufferedImage; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import org.apache.fop.apps.AbstractRendererConfigParserTester; import org.apache.fop.apps.BitmapRendererConfBuilder; import org.apache.fop.render.bitmap.BitmapRendererConfig.BitmapRendererConfigParser; @@ -36,10 +41,6 @@ import static org.apache.fop.render.bitmap.BitmapRendererOption.COLOR_MODE_RGBA; import static org.apache.fop.render.bitmap.BitmapRendererOption.JAVA2D_TRANSPARENT_PAGE_BACKGROUND; import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_QUALITY; import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_SPEED; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; public class AbstractBitmapRendererConfigParserTester extends AbstractRendererConfigParserTester<BitmapRendererConfBuilder, BitmapRendererConfig> { diff --git a/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfiguratorTest.java b/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfiguratorTest.java index 3e0c8c203..dcbb27754 100644 --- a/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfiguratorTest.java +++ b/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfiguratorTest.java @@ -23,6 +23,11 @@ import java.awt.image.BufferedImage; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + import org.apache.fop.apps.AbstractRendererConfiguratorTest; import org.apache.fop.apps.BitmapRendererConfBuilder; import org.apache.fop.render.intermediate.IFDocumentHandler; @@ -35,10 +40,6 @@ import static org.apache.fop.render.bitmap.BitmapRendererOption.COLOR_MODE_RGB; import static org.apache.fop.render.bitmap.BitmapRendererOption.COLOR_MODE_RGBA; import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_QUALITY; import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_SPEED; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; public abstract class AbstractBitmapRendererConfiguratorTest extends AbstractRendererConfiguratorTest<BitmapRendererConfigurator, BitmapRendererConfBuilder> { diff --git a/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java index d33076983..8a5c2a72d 100644 --- a/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java +++ b/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java @@ -21,16 +21,16 @@ package org.apache.fop.render.bitmap; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import org.apache.xmlgraphics.image.writer.Endianness; import org.apache.fop.apps.FopConfBuilder; import org.apache.fop.apps.TIFFRendererConfBuilder; import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - public class TIFFRendererConfigParserTestCase extends AbstractBitmapRendererConfigParserTester { diff --git a/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java index b5e6318ce..e340830f4 100644 --- a/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java +++ b/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java @@ -23,6 +23,10 @@ import java.awt.image.BufferedImage; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import org.apache.xmlgraphics.image.writer.Endianness; import org.apache.fop.apps.FopConfBuilder; @@ -32,9 +36,6 @@ import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser; import static org.apache.fop.render.bitmap.TIFFCompressionValue.CCITT_T4; import static org.apache.fop.render.bitmap.TIFFCompressionValue.CCITT_T6; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; public class TIFFRendererConfiguratorTestCase extends AbstractBitmapRendererConfiguratorTest { diff --git a/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java b/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java index 6e48845c1..e3f892e7c 100644 --- a/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java +++ b/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java @@ -19,15 +19,15 @@ package org.apache.fop.render.extensions.prepress; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - import java.awt.Dimension; import java.awt.Rectangle; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + /** * Tests for the fox:bleed, fox:crop-offset, fox:crop-box extension properties. */ diff --git a/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java b/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java index ff07e63ce..9de045cf7 100644 --- a/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java +++ b/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java @@ -19,14 +19,14 @@ package org.apache.fop.render.extensions.prepress; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - import java.awt.geom.Point2D; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + /** * Tests for the fox:scale extension property. */ diff --git a/test/java/org/apache/fop/render/intermediate/AbstractIFPainterTestCase.java b/test/java/org/apache/fop/render/intermediate/AbstractIFPainterTestCase.java index be8b5d718..ec0f35737 100644 --- a/test/java/org/apache/fop/render/intermediate/AbstractIFPainterTestCase.java +++ b/test/java/org/apache/fop/render/intermediate/AbstractIFPainterTestCase.java @@ -26,15 +26,15 @@ import org.junit.Before; import org.junit.Test; import org.w3c.dom.Document; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; import org.apache.fop.render.RenderingContext; import org.apache.fop.traits.BorderProps; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - public class AbstractIFPainterTestCase { private AbstractIFPainter<?> sut; diff --git a/test/java/org/apache/fop/render/intermediate/ArcToBezierCurveTransformerTestCase.java b/test/java/org/apache/fop/render/intermediate/ArcToBezierCurveTransformerTestCase.java index 61093c629..039ddcf90 100644 --- a/test/java/org/apache/fop/render/intermediate/ArcToBezierCurveTransformerTestCase.java +++ b/test/java/org/apache/fop/render/intermediate/ArcToBezierCurveTransformerTestCase.java @@ -76,4 +76,4 @@ public class ArcToBezierCurveTransformerTestCase { fail("Angle " + angle + " is in (0, " + Math.PI / 2 + ")"); } } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java b/test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java index f0e9522d9..4a89b3ac6 100644 --- a/test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java +++ b/test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java @@ -575,4 +575,4 @@ public class BorderPainterTestCase { } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java b/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java index 4df3fe278..5546e5905 100644 --- a/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java +++ b/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java @@ -19,14 +19,6 @@ package org.apache.fop.render.intermediate; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentMatcher; @@ -36,6 +28,14 @@ import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + import org.apache.fop.fo.FOElementMapping; import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.fo.extensions.InternalElementMapping; diff --git a/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java b/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java index c5aad66d0..757d6620b 100644 --- a/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java +++ b/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java @@ -20,10 +20,6 @@ package org.apache.fop.render.intermediate; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - import org.junit.Before; import org.junit.Test; import org.mockito.InOrder; @@ -32,6 +28,10 @@ import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + import org.apache.fop.render.intermediate.IFStructureTreeBuilder.SAXEventRecorder; import org.apache.fop.util.XMLUtil; diff --git a/test/java/org/apache/fop/render/java2d/Java2DRendererConfigParserTestcase.java b/test/java/org/apache/fop/render/java2d/Java2DRendererConfigParserTestcase.java index 00631af4b..e87c8713d 100644 --- a/test/java/org/apache/fop/render/java2d/Java2DRendererConfigParserTestcase.java +++ b/test/java/org/apache/fop/render/java2d/Java2DRendererConfigParserTestcase.java @@ -21,17 +21,14 @@ package org.apache.fop.render.java2d; import org.junit.Test; -import org.apache.avalon.framework.configuration.Configuration; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import org.apache.fop.apps.AbstractRendererConfigParserTester; -import org.apache.fop.apps.FOPException; import org.apache.fop.apps.Java2DRendererConfBuilder; import org.apache.fop.render.java2d.Java2DRendererConfig.Java2DRendererConfigParser; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - public class Java2DRendererConfigParserTestcase extends AbstractRendererConfigParserTester<Java2DRendererConfBuilder, Java2DRendererConfig> { diff --git a/test/java/org/apache/fop/render/pcl/PCLRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/pcl/PCLRendererConfigParserTestCase.java index 113c3e2bd..caf534854 100644 --- a/test/java/org/apache/fop/render/pcl/PCLRendererConfigParserTestCase.java +++ b/test/java/org/apache/fop/render/pcl/PCLRendererConfigParserTestCase.java @@ -21,13 +21,13 @@ package org.apache.fop.render.pcl; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.fop.apps.AbstractRendererConfigParserTester; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.MimeConstants; import org.apache.fop.render.pcl.PCLRendererConfig.PCLRendererConfigParser; -import static org.junit.Assert.assertEquals; - public class PCLRendererConfigParserTestCase extends AbstractRendererConfigParserTester<PCLRendererConfBuilder, PCLRendererConfig> { diff --git a/test/java/org/apache/fop/render/pcl/PCLRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/pcl/PCLRendererConfiguratorTestCase.java index 024104179..fc7175ad6 100644 --- a/test/java/org/apache/fop/render/pcl/PCLRendererConfiguratorTestCase.java +++ b/test/java/org/apache/fop/render/pcl/PCLRendererConfiguratorTestCase.java @@ -19,16 +19,16 @@ package org.apache.fop.render.pcl; import org.junit.Test; -import org.apache.fop.apps.AbstractRendererConfiguratorTest; -import org.apache.fop.apps.FOPException; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.render.pcl.PCLRendererConfig.PCLRendererConfigParser; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; +import org.apache.fop.apps.AbstractRendererConfiguratorTest; +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.render.pcl.PCLRendererConfig.PCLRendererConfigParser; + public class PCLRendererConfiguratorTestCase extends AbstractRendererConfiguratorTest<PCLRendererConfigurator, PCLRendererConfBuilder> { diff --git a/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java index 94c842e68..b2b77e842 100644 --- a/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java @@ -21,14 +21,19 @@ package org.apache.fop.render.pdf; import java.io.File; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import org.junit.Test; import org.xml.sax.SAXException; +import static org.junit.Assert.fail; + import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.events.EventChecker; +import org.apache.fop.pdf.PDFAMode; import org.apache.fop.pdf.PDFConformanceException; - -import static org.junit.Assert.fail; +import org.apache.fop.svg.SVGEventProducer; /** * Tests PDF/A-1 functionality. @@ -108,4 +113,17 @@ public class PDFAConformanceTestCase extends BasePDFTest { } } + @Test + public void svgTransparency() throws Exception { + Map<String, Object> params = new HashMap<String, Object>(); + params.put("pdfProfile", PDFAMode.PDFA_1B); + EventChecker eventChecker = new EventChecker(SVGEventProducer.class.getName() + + ".transparencyIgnored", params); + FOUserAgent ua = getUserAgent(); + ua.getEventBroadcaster().addEventListener(eventChecker); + File foFile = new File(foBaseDir, "svg-transparency.fo"); + convertFO(foFile, ua, dumpPDF); + eventChecker.end(); + } + } diff --git a/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java b/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java index 1606bf073..6ff40b3c3 100644 --- a/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java @@ -19,15 +19,14 @@ package org.apache.fop.render.pdf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - import java.util.Calendar; import java.util.TimeZone; -import org.apache.fop.pdf.PDFDocument; -import org.apache.fop.pdf.PDFInfo; -import org.apache.fop.pdf.PDFMetadata; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter; import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema; @@ -35,7 +34,10 @@ import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter; import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFAdapter; import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema; -import org.junit.Test; + +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.PDFInfo; +import org.apache.fop.pdf.PDFMetadata; /** * Test case for PDF/A metadata handling. diff --git a/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java b/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java index fee2c07aa..bb0f2f92e 100644 --- a/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java @@ -19,13 +19,14 @@ package org.apache.fop.render.pdf; -import static org.junit.Assert.assertEquals; - import java.io.StringWriter; -import org.apache.fop.pdf.CMapBuilder; import org.junit.Test; +import static org.junit.Assert.assertEquals; + +import org.apache.fop.pdf.CMapBuilder; + /** Simple sanity test of the PDFCmap class */ public class PDFCMapTestCase { private static final String EOL = "\n"; @@ -60,8 +61,7 @@ public class PDFCMapTestCase { + "end" + EOL + "end" + EOL + "%%EndResource" + EOL - + "%%EOF" + EOL - ; + + "%%EOF" + EOL; final StringWriter w = new StringWriter(); final CMapBuilder builder = new CMapBuilder(w, "test"); diff --git a/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java b/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java index 34647818a..fc6212dcd 100644 --- a/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java @@ -19,9 +19,6 @@ package org.apache.fop.render.pdf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.io.File; import java.io.IOException; import java.util.StringTokenizer; @@ -30,6 +27,9 @@ import org.junit.Ignore; import org.junit.Test; import org.xml.sax.SAXException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import org.apache.fop.apps.FOUserAgent; /** Test that characters are correctly encoded in a generated PDF file */ diff --git a/test/java/org/apache/fop/render/pdf/PDFGraphicsPainterTestCase.java b/test/java/org/apache/fop/render/pdf/PDFGraphicsPainterTestCase.java index 4f3a5e628..3130a73e7 100644 --- a/test/java/org/apache/fop/render/pdf/PDFGraphicsPainterTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFGraphicsPainterTestCase.java @@ -24,12 +24,12 @@ import java.io.IOException; import org.junit.Before; import org.junit.Test; -import org.apache.fop.pdf.PDFNumber; - import static org.mockito.Matchers.endsWith; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import org.apache.fop.pdf.PDFNumber; + public class PDFGraphicsPainterTestCase { private PDFGraphicsPainter sut; diff --git a/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java b/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java index f431b3ee9..db1757847 100644 --- a/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java @@ -24,17 +24,17 @@ import java.awt.Rectangle; import org.junit.Test; -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.fo.Constants; -import org.apache.fop.render.intermediate.IFContext; -import org.apache.fop.traits.BorderProps; - import static org.mockito.Matchers.endsWith; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.Constants; +import org.apache.fop.render.intermediate.IFContext; +import org.apache.fop.traits.BorderProps; + public class PDFPainterTestCase { @Test diff --git a/test/java/org/apache/fop/render/pdf/PDFRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/pdf/PDFRendererConfigParserTestCase.java index 2d3dfb760..4dd3a6610 100644 --- a/test/java/org/apache/fop/render/pdf/PDFRendererConfigParserTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFRendererConfigParserTestCase.java @@ -21,6 +21,10 @@ package org.apache.fop.render.pdf; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import org.apache.fop.apps.AbstractRendererConfigParserTester; import org.apache.fop.apps.PDFRendererConfBuilder; import org.apache.fop.pdf.PDFAMode; @@ -28,10 +32,6 @@ import org.apache.fop.pdf.PDFXMode; import org.apache.fop.pdf.Version; import org.apache.fop.render.pdf.PDFRendererConfig.PDFRendererConfigParser; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - public class PDFRendererConfigParserTestCase extends AbstractRendererConfigParserTester<PDFRendererConfBuilder, PDFRendererConfig> { diff --git a/test/java/org/apache/fop/render/pdf/PDFRendererOptionsConfigTestCase.java b/test/java/org/apache/fop/render/pdf/PDFRendererOptionsConfigTestCase.java index 489d4dc96..699a8a186 100644 --- a/test/java/org/apache/fop/render/pdf/PDFRendererOptionsConfigTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFRendererOptionsConfigTestCase.java @@ -29,6 +29,8 @@ import java.util.Map; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.fop.pdf.PDFAMode; import org.apache.fop.pdf.PDFEncryptionParams; import org.apache.fop.pdf.PDFXMode; @@ -40,7 +42,6 @@ import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE; import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE; import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE; import static org.apache.fop.render.pdf.PDFRendererOption.VERSION; -import static org.junit.Assert.assertEquals; public class PDFRendererOptionsConfigTestCase { @@ -51,7 +52,7 @@ public class PDFRendererOptionsConfigTestCase { static { final EnumMap<PDFRendererOption, Object> props = new EnumMap<PDFRendererOption, Object>(PDFRendererOption.class); - for(PDFRendererOption option : PDFRendererOption.values()) { + for (PDFRendererOption option : PDFRendererOption.values()) { props.put(option, option.getDefaultValue()); } DEFAULT_OPTIONS = Collections.unmodifiableMap(props); @@ -102,7 +103,7 @@ public class PDFRendererOptionsConfigTestCase { assertEncryptionParamsEquals(expectedEncryptionParams, actual.getEncryptionParameters()); } - private static void assertEncryptionParamsEquals(PDFEncryptionParams expected, + private static void assertEncryptionParamsEquals(PDFEncryptionParams expected, PDFEncryptionParams actual) { assertEquals(expected == null, actual == null); if (actual != null) { diff --git a/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java b/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java index d084aa618..965a8e30e 100644 --- a/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java @@ -19,14 +19,14 @@ package org.apache.fop.render.pdf; -import static org.junit.Assert.fail; - import java.io.File; import java.io.IOException; import org.junit.Test; import org.xml.sax.SAXException; +import static org.junit.Assert.fail; + import org.apache.fop.apps.FOUserAgent; /** diff --git a/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java b/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java index f41520bf3..e74251be1 100644 --- a/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java +++ b/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java @@ -28,8 +28,6 @@ import org.junit.runners.Suite.SuiteClasses; * A test suite for org.apache.fop.render.pdf.* */ @RunWith(Suite.class) -@SuiteClasses({ - PDFRendererConfigParserTestCase.class -}) +@SuiteClasses(PDFRendererConfigParserTestCase.class) public final class RenderPDFTestSuite { } diff --git a/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java b/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java index dcbc2d757..eb25c3f94 100644 --- a/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java +++ b/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java @@ -19,11 +19,11 @@ package org.apache.fop.render.ps; -import static org.junit.Assert.assertEquals; - import java.io.File; import java.io.IOException; +import static org.junit.Assert.assertEquals; + import org.apache.xmlgraphics.ps.PSResource; import org.apache.xmlgraphics.ps.dsc.DSCException; import org.apache.xmlgraphics.ps.dsc.DSCParser; diff --git a/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java b/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java index 458033dad..53654d76a 100644 --- a/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java +++ b/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java @@ -27,17 +27,16 @@ import java.io.IOException; import org.junit.Test; -import org.apache.xmlgraphics.image.loader.ImageSize; -import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG; - -import org.apache.fop.render.RawPNGTestUtil; - import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; - import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.apache.xmlgraphics.image.loader.ImageSize; +import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG; + +import org.apache.fop.render.RawPNGTestUtil; + public class ImageEncoderPNGTestCase { @Test diff --git a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java index ba0598b52..02e96806f 100644 --- a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java +++ b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java @@ -18,15 +18,15 @@ /* $Id$ */ package org.apache.fop.render.ps; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.io.File; import java.io.IOException; import java.io.InputStream; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.ps.DSCConstants; diff --git a/test/java/org/apache/fop/render/ps/PSPainterTestCase.java b/test/java/org/apache/fop/render/ps/PSPainterTestCase.java index 79e5bd9b6..b678fdb4b 100644 --- a/test/java/org/apache/fop/render/ps/PSPainterTestCase.java +++ b/test/java/org/apache/fop/render/ps/PSPainterTestCase.java @@ -146,11 +146,11 @@ public class PSPainterTestCase { int y = 100000; int letterSpacing = 0; int wordSpacing = 0; - int dp[][] = {{100, 100, 0, 0}, null, null, {200, 200, -100, -100}}; - double X = (x + dp[0][0]) / 1000.0; - double Y = (y - dp[0][1]) / 1000.0; - when(psGenerator.formatDouble(X)).thenReturn("100.100"); - when(psGenerator.formatDouble(Y)).thenReturn("99.900"); + int[][] dp = {{100, 100, 0, 0}, null, null, {200, 200, -100, -100}}; + double xAsDouble = (x + dp[0][0]) / 1000.0; + double yAsDouble = (y - dp[0][1]) / 1000.0; + when(psGenerator.formatDouble(xAsDouble)).thenReturn("100.100"); + when(psGenerator.formatDouble(yAsDouble)).thenReturn("99.900"); String text = "Hello Mock!"; try { psPainter.drawText(x, y, letterSpacing, wordSpacing, dp, text); diff --git a/test/java/org/apache/fop/render/ps/PSRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/ps/PSRendererConfigParserTestCase.java index fe59143b4..45642764c 100644 --- a/test/java/org/apache/fop/render/ps/PSRendererConfigParserTestCase.java +++ b/test/java/org/apache/fop/render/ps/PSRendererConfigParserTestCase.java @@ -21,14 +21,14 @@ package org.apache.fop.render.ps; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.fop.apps.AbstractRendererConfigParserTester; import org.apache.fop.apps.PSRendererConfBuilder; import org.apache.fop.render.ps.PSRendererConfig.PSRendererConfigParser; -import static org.junit.Assert.assertEquals; - public class PSRendererConfigParserTestCase extends AbstractRendererConfigParserTester<PSRendererConfBuilder, PSRendererConfig> { diff --git a/test/java/org/apache/fop/render/ps/PSRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/ps/PSRendererConfiguratorTestCase.java index 4d42a0aab..67ba24763 100644 --- a/test/java/org/apache/fop/render/ps/PSRendererConfiguratorTestCase.java +++ b/test/java/org/apache/fop/render/ps/PSRendererConfiguratorTestCase.java @@ -19,16 +19,16 @@ package org.apache.fop.render.ps; import org.junit.Test; -import org.apache.fop.apps.AbstractRendererConfiguratorTest; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.apps.PSRendererConfBuilder; -import org.apache.fop.render.ps.PSRendererConfig.PSRendererConfigParser; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; +import org.apache.fop.apps.AbstractRendererConfiguratorTest; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.apps.PSRendererConfBuilder; +import org.apache.fop.render.ps.PSRendererConfig.PSRendererConfigParser; + public class PSRendererConfiguratorTestCase extends AbstractRendererConfiguratorTest<PSRendererConfigurator, PSRendererConfBuilder> { private PSRenderingUtil psUtil; diff --git a/test/java/org/apache/fop/render/ps/PSRenderingUtilTestCase.java b/test/java/org/apache/fop/render/ps/PSRenderingUtilTestCase.java index 3f1088fe1..0a2c895be 100644 --- a/test/java/org/apache/fop/render/ps/PSRenderingUtilTestCase.java +++ b/test/java/org/apache/fop/render/ps/PSRenderingUtilTestCase.java @@ -23,13 +23,13 @@ import java.io.IOException; import org.junit.Test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.fop.render.ps.extensions.PSPageTrailerCodeBefore; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - public class PSRenderingUtilTestCase { private final String content = "<< /MyEntry 0 >> command"; diff --git a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java index bfdb5f968..4f06938d2 100644 --- a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java +++ b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java @@ -19,11 +19,6 @@ package org.apache.fop.render.ps; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -33,6 +28,11 @@ import java.util.Set; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.ps.DSCConstants; diff --git a/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java b/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java index b48da4186..29a3a7bd3 100644 --- a/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java +++ b/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java @@ -29,6 +29,8 @@ import java.io.IOException; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.commons.io.FileUtils; import org.apache.batik.ext.awt.RadialGradientPaint; @@ -36,8 +38,6 @@ import org.apache.batik.ext.awt.RadialGradientPaint; import org.apache.xmlgraphics.java2d.GraphicContext; import org.apache.xmlgraphics.ps.PSGenerator; -import static org.junit.Assert.assertEquals; - public class PSSVGGraphics2DTestCase { float cx = 841.891f; diff --git a/test/java/org/apache/fop/render/ps/svg/PSSVGLinearGraphics2DTestCase.java b/test/java/org/apache/fop/render/ps/svg/PSSVGLinearGraphics2DTestCase.java index 283d3f4ad..3a6db4396 100644 --- a/test/java/org/apache/fop/render/ps/svg/PSSVGLinearGraphics2DTestCase.java +++ b/test/java/org/apache/fop/render/ps/svg/PSSVGLinearGraphics2DTestCase.java @@ -29,6 +29,8 @@ import java.io.IOException; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.commons.io.FileUtils; import org.apache.batik.ext.awt.LinearGradientPaint; @@ -36,13 +38,11 @@ import org.apache.batik.ext.awt.LinearGradientPaint; import org.apache.xmlgraphics.java2d.GraphicContext; import org.apache.xmlgraphics.ps.PSGenerator; -import static org.junit.Assert.assertEquals; - public class PSSVGLinearGraphics2DTestCase { float startX = 115f; float endX = 15f; float startY = 285f; - float endY=15f; + float endY = 15f; float[] fractions = {0.0f, 1.0f}; /** diff --git a/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java b/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java index c5821fff1..4c3c8446e 100644 --- a/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java +++ b/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java @@ -21,13 +21,14 @@ package org.apache.fop.render.rtf; import java.io.StringWriter; +import org.junit.Test; + import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFile; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; -import org.junit.Test; /** * Test for http://issues.apache.org/bugzilla/show_bug.cgi?id=39607 diff --git a/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java b/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java index d8296fc33..5b294bd9b 100644 --- a/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java +++ b/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java @@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses; * Test suite for FOP's RTF library. */ @RunWith(Suite.class) -@SuiteClasses({ Bug39607TestCase.class }) +@SuiteClasses(Bug39607TestCase.class) public class RichTextFormatTestSuite { } diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/BasicLink.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/BasicLink.java index 07085059d..9df1c26ef 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/BasicLink.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/BasicLink.java @@ -27,17 +27,15 @@ package org.apache.fop.render.rtf.rtflib.testdocs; +import java.io.IOException; + import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfHyperLink; - -import java.io.IOException; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; /** * Class <code>BasicLink</code> here. - * - * @author <a href="mailto:mks@ANDREAS">Andreas Putz</a> */ public class BasicLink extends TestDocument { diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/CreateTestDocuments.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/CreateTestDocuments.java index 16460cd1c..7f17514ef 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/CreateTestDocuments.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/CreateTestDocuments.java @@ -29,11 +29,8 @@ package org.apache.fop.render.rtf.rtflib.testdocs; import java.io.File; import java.io.IOException; -//import org.apache.fop.render.rtf.rtflib.jfor.main.JForVersionInfo; /** Create test RTF documents from classes found in this package. - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch - * @author Andreas Putz a.putz@skynamics.com */ public class CreateTestDocuments { diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java index 3329b26b9..1af4c7bed 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java @@ -33,8 +33,6 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.ITableColumnsInfo; * to create documents without worrying about nested tables handling. * Might need to be replaced by more complete version in some sample * documents created by this package. - * - * @author bdelacretaz@codeconsult.ch */ class DummyTableColumnsInfo implements ITableColumnsInfo { diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ExternalGraphic.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ExternalGraphic.java index b957bc1fa..1127f3e72 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ExternalGraphic.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ExternalGraphic.java @@ -27,16 +27,14 @@ package org.apache.fop.render.rtf.rtflib.testdocs; +import java.io.IOException; + import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; - -import java.io.IOException; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; /** * Generate a test document containing external graphics. - * - * @author <a href="mailto:a.putz@skynamics.com">Andreas Putz</a> */ class ExternalGraphic extends TestDocument { private String file = "file:///tmp/jfor-images/logo."; diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java index 3ce05c606..6f4e27a59 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java @@ -30,13 +30,13 @@ package org.apache.fop.render.rtf.rtflib.testdocs; import java.io.IOException; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; /** Generates a simple RTF test document for the jfor rtflib package. */ diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java index f1817bf03..9be5e899a 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java @@ -32,11 +32,10 @@ import java.io.IOException; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; /** Generates an RTF test document containing merged table cells - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch */ class MergedTableCells extends TestDocument { diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java index 72dad7e98..c11fbc334 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java @@ -30,14 +30,13 @@ package org.apache.fop.render.rtf.rtflib.testdocs; import java.io.IOException; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; /** Generates an RTF document to test nested tables with the jfor rtflib package. - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch */ class NestedTable extends TestDocument { diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ParagraphAlignment.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ParagraphAlignment.java index 2b38aa789..edce3264a 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ParagraphAlignment.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ParagraphAlignment.java @@ -27,14 +27,13 @@ package org.apache.fop.render.rtf.rtflib.testdocs; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfText; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes; /** Generates a simple RTF test document for the jfor rtflib package. - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch */ public class ParagraphAlignment extends TestDocument { diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java index 2ca16c0e5..ca6ce79bc 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java @@ -30,11 +30,10 @@ package org.apache.fop.render.rtf.rtflib.testdocs; import java.io.IOException; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; /** Generates a simple RTF test document for the jfor rtflib package. - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch */ class SimpleDocument diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java index eff3aa7ff..e817f6a13 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java @@ -30,15 +30,14 @@ package org.apache.fop.render.rtf.rtflib.testdocs; import java.io.IOException; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListStyle; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListStyleNumber; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; /** Generates a simple RTF test document for the jfor rtflib package. - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch */ class SimpleLists extends TestDocument { diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java index cf84b3ec4..10ddc11e7 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java @@ -32,11 +32,10 @@ import java.io.IOException; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; /** Generates a simple RTF test document for the jfor rtflib package. - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch */ class SimpleTable extends TestDocument { /** generate the body of the test document */ diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java index 5274dc32e..266903766 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java @@ -27,19 +27,17 @@ package org.apache.fop.render.rtf.rtflib.testdocs; -import java.util.Date; import java.io.File; -import java.io.IOException; import java.io.FileWriter; +import java.io.IOException; +import java.util.Date; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFile; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; -//import org.apache.fop.render.rtf.rtflib.jfor.main.JForVersionInfo; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; /** Base class for generating RTF documents used to test the jfor rtflib package. - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch */ abstract class TestDocument { diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java index 4ab48acb0..bb0614cee 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java @@ -29,14 +29,13 @@ package org.apache.fop.render.rtf.rtflib.testdocs; import java.io.IOException; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfText; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes; /** Generates a simple RTF test document for the jfor rtflib package. - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch */ class TextAttributes extends TestDocument { diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java index 4359822f6..a206e014f 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java @@ -30,11 +30,10 @@ package org.apache.fop.render.rtf.rtflib.testdocs; import java.io.IOException; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; /** Generates an RTF document to test the WhitespaceCollapser - * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch */ class Whitespace extends TestDocument { diff --git a/test/java/org/apache/fop/render/txt/TxtRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/txt/TxtRendererConfigParserTestCase.java index a7ae52c65..30fed05ea 100644 --- a/test/java/org/apache/fop/render/txt/TxtRendererConfigParserTestCase.java +++ b/test/java/org/apache/fop/render/txt/TxtRendererConfigParserTestCase.java @@ -21,13 +21,12 @@ package org.apache.fop.render.txt; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.fop.apps.AbstractRendererConfigParserTester; import org.apache.fop.apps.TxtRendererConfBuilder; -import org.apache.fop.render.RendererConfig.RendererConfigParser; -import org.apache.fop.render.txt.TxtRendererConfig.TxtRendererOption; import org.apache.fop.render.txt.TxtRendererConfig.TxtRendererConfigParser; - -import static org.junit.Assert.assertEquals; +import org.apache.fop.render.txt.TxtRendererConfig.TxtRendererOption; public class TxtRendererConfigParserTestCase extends AbstractRendererConfigParserTester<TxtRendererConfBuilder, TxtRendererConfig> { diff --git a/test/java/org/apache/fop/svg/NativeTextPainterTest.java b/test/java/org/apache/fop/svg/NativeTextPainterTest.java new file mode 100644 index 000000000..1c2c3b582 --- /dev/null +++ b/test/java/org/apache/fop/svg/NativeTextPainterTest.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg; + +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.io.File; +import java.io.IOException; + +import org.w3c.dom.Document; + +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.bridge.GVTBuilder; +import org.apache.batik.dom.svg.SAXSVGDocumentFactory; +import org.apache.batik.gvt.GraphicsNode; +import org.apache.batik.gvt.TextPainter; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.base14.Base14FontCollection; +import org.apache.fop.svg.font.FOPFontFamilyResolverImpl; + +abstract class NativeTextPainterTest { + + protected final void runTest(String testcase, OperatorValidator validator) throws Exception { + FontInfo fontInfo = createFontInfo(); + BridgeContext bridgeContext = createBridgeContext(fontInfo); + GraphicsNode svg = loadSVG(bridgeContext, testcase); + Graphics2D g2d = createGraphics2D(fontInfo, validator); + svg.paint(g2d); + validator.end(); + } + + private FontInfo createFontInfo() { + FontInfo fontInfo = new FontInfo(); + new Base14FontCollection(true).setup(0, fontInfo); + return fontInfo; + } + + private BridgeContext createBridgeContext(FontInfo fontInfo) { + FOUserAgent userAgent = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent(); + SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new FOPFontFamilyResolverImpl(fontInfo), + new AffineTransform()); + BridgeContext bridgeContext = new BridgeContext(svgUserAgent); + bridgeContext.setTextPainter(createTextPainter(fontInfo)); + return bridgeContext; + } + + protected abstract TextPainter createTextPainter(FontInfo fontInfo); + + private GraphicsNode loadSVG(BridgeContext bridgeContext, String resourceName) throws IOException { + SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(null); + Document svg = factory.createDocument(null, getClass().getResourceAsStream(resourceName)); + GVTBuilder builder = new GVTBuilder(); + return builder.build(bridgeContext, svg); + } + + protected abstract Graphics2D createGraphics2D(FontInfo fontInfo, OperatorValidator validator); + +} diff --git a/test/java/org/apache/fop/svg/OperatorValidator.java b/test/java/org/apache/fop/svg/OperatorValidator.java new file mode 100644 index 000000000..e94c8e404 --- /dev/null +++ b/test/java/org/apache/fop/svg/OperatorValidator.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg; + +import java.util.LinkedList; +import java.util.Queue; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +class OperatorValidator { + + private interface Match { + + boolean match(String line); + } + + private static class MatchSequence implements OperatorValidator.Match { + + private final Queue<OperatorValidator.Match> expectedMatches = new LinkedList<OperatorValidator.Match>(); + + private OperatorValidator.Match currentMatch; + + private static final OperatorValidator.Match FINAL_MATCH = new Match() { + + public boolean match(String line) { + return false; + } + }; + + public boolean isExhausted() { + return currentMatch == FINAL_MATCH; + } + + public void addMatch(OperatorValidator.Match match) { + if (currentMatch == null) { + currentMatch = match; + } else { + expectedMatches.add(match); + } + } + + public boolean match(String line) { + boolean match = currentMatch.match(line); + if (match) { + if (expectedMatches.isEmpty()) { + currentMatch = FINAL_MATCH; + } else { + currentMatch = expectedMatches.remove(); + } + } + return match; + } + } + + private static class OperatorMatch implements OperatorValidator.Match { + + final String operator; + + final String line; + + OperatorMatch(String operator, String line) { + this.operator = operator; + this.line = line; + } + + public boolean match(String line) { + if (line.contains(operator)) { + assertEquals(this.line, line); + return true; + } + return false; + } + } + + private final OperatorValidator.MatchSequence matchSequence = new MatchSequence(); + + public OperatorValidator addOperatorMatch(String operator, String expectedLine) { + matchSequence.addMatch(new OperatorMatch(operator, expectedLine)); + return this; + } + + public void check(String line) { + matchSequence.match(line); + } + + public void end() { + assertTrue("Expected operators remain", matchSequence.isExhausted()); + } + +} diff --git a/test/java/org/apache/fop/svg/PDFTextPainterTestCase.java b/test/java/org/apache/fop/svg/PDFTextPainterTestCase.java new file mode 100644 index 000000000..e7e47e7ba --- /dev/null +++ b/test/java/org/apache/fop/svg/PDFTextPainterTestCase.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg; + +import java.awt.Graphics2D; +import java.io.StringWriter; + +import org.junit.Test; + +import org.apache.batik.gvt.TextPainter; + +import org.apache.xmlgraphics.java2d.GraphicContext; + +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.pdf.PDFDocument; + +public class PDFTextPainterTestCase extends NativeTextPainterTest { + + private static class OperatorCheckingPDFGraphics2D extends PDFGraphics2D { + + OperatorCheckingPDFGraphics2D(FontInfo fontInfo, final OperatorValidator validator) { + super(false, fontInfo, new PDFDocument("test"), null, null, null, 0, null); + this.currentStream = new StringWriter() { + + @Override + public void write(String str) { + validator.check(str); + } + + }; + } + } + + @Override + protected TextPainter createTextPainter(FontInfo fontInfo) { + return new PDFTextPainter(fontInfo); + } + + @Override + protected Graphics2D createGraphics2D(FontInfo fontInfo, OperatorValidator validator) { + PDFGraphics2D g2d = new OperatorCheckingPDFGraphics2D(fontInfo, validator); + g2d.setGraphicContext(new GraphicContext()); + return g2d; + } + + @Test + public void testRotatedGlyph() throws Exception { + runTest("rotated-glyph.svg", new OperatorValidator() + .addOperatorMatch("Tm", "1 0 0 -1 40 110 Tm ") + .addOperatorMatch("TJ", "[(A)] TJ\n") + .addOperatorMatch("Tm", "0.70710677 0.7071068 0.7071068 -0.70710677 106.69999695 110 Tm ") + .addOperatorMatch("TJ", "[(B)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 173.3999939 110 Tm ") + .addOperatorMatch("TJ", "[(C)] TJ\n")); + } + + @Test + public void testDxDy() throws Exception { + runTest("dx-dy.svg", new OperatorValidator() + .addOperatorMatch("Tm", "1 0 0 -1 55 35 Tm ") + .addOperatorMatch("TJ", "[(ABCDE)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 55 75 Tm ") + .addOperatorMatch("TJ", "[(A)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 69 85 Tm ") + .addOperatorMatch("TJ", "[(B)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 109 80 Tm ") + .addOperatorMatch("TJ", "[(C)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 91 65 Tm ") + .addOperatorMatch("TJ", "[(D)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 127 75 Tm ") + .addOperatorMatch("TJ", "[(E)] TJ\n")); + } + + @Test + public void testSpacing() throws Exception { + runTest("spacing.svg", new OperatorValidator() + .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ") + .addOperatorMatch("TJ", "[(V) 80 (A) 70 (V)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ") + .addOperatorMatch("TJ", "[(V) 80 (A) 70 (V)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ") + .addOperatorMatch("TJ", "[(V) -20 (A) -30 (V)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ") + .addOperatorMatch("TJ", "[(ab) -111 ( ) -389 (cd)] TJ\n")); + } + + @Test + public void testGlyphOrientation() throws Exception { + runTest("glyph-orientation.svg", new OperatorValidator() + .addOperatorMatch("Tm", "0 1 1 0 738.5 0 Tm ") + .addOperatorMatch("TJ", "[(A)] TJ\n") + .addOperatorMatch("Tm", "0 1 1 0 738.5 667 Tm ") + .addOperatorMatch("TJ", "[(B)] TJ\n") + .addOperatorMatch("Tm", "0 1 1 0 738.5 1334 Tm ") + .addOperatorMatch("TJ", "[(C)] TJ\n") + .addOperatorMatch("Tm", "0 1 1 0 738.5 2056 Tm ") + .addOperatorMatch("TJ", "[(D)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 2149 718 Tm ") + .addOperatorMatch("TJ", "[(E)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 2165.5 1643 Tm ") + .addOperatorMatch("TJ", "[(F)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 2124 2568 Tm ") + .addOperatorMatch("TJ", "[(G)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 2138.5 3493 Tm ") + .addOperatorMatch("TJ", "[(H)] TJ\n") + .addOperatorMatch("Tm", "0 -1 -1 0 718 5000 Tm ") + .addOperatorMatch("TJ", "[(I)] TJ\n") + .addOperatorMatch("Tm", "0 -1 -1 0 1643 5000 Tm ") + .addOperatorMatch("TJ", "[(J)] TJ\n") + .addOperatorMatch("Tm", "0 -1 -1 0 2568 5000 Tm ") + .addOperatorMatch("TJ", "[(K)] TJ\n") + .addOperatorMatch("Tm", "0 -1 -1 0 3493 5000 Tm ") + .addOperatorMatch("TJ", "[(L)] TJ\n")); + } + + @Test + public void testBaselineShift() throws Exception { + runTest("baseline-shift.svg", new OperatorValidator() + .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ") + .addOperatorMatch("TJ", "[(AB)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 1334 -462.5 Tm ") + .addOperatorMatch("TJ", "[(CD)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 2778 0 Tm ") + .addOperatorMatch("TJ", "[(EF)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 4056 462.5 Tm ") + .addOperatorMatch("TJ", "[(GH)] TJ\n") + .addOperatorMatch("Tm", "1 0 0 -1 5556 0 Tm ") + .addOperatorMatch("TJ", "[(IJ)] TJ\n")); + } + +} diff --git a/test/java/org/apache/fop/svg/PSTextPainterTestCase.java b/test/java/org/apache/fop/svg/PSTextPainterTestCase.java new file mode 100644 index 000000000..2d5de7455 --- /dev/null +++ b/test/java/org/apache/fop/svg/PSTextPainterTestCase.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg; + +import java.awt.Graphics2D; +import java.io.IOException; + +import org.junit.Test; + +import org.apache.commons.io.output.NullOutputStream; + +import org.apache.batik.gvt.TextPainter; + +import org.apache.xmlgraphics.java2d.GraphicContext; +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; +import org.apache.xmlgraphics.ps.PSGenerator; + +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.render.ps.PSTextPainter; + +public class PSTextPainterTestCase extends NativeTextPainterTest { + + private static class OperatorCheckingPSGraphics2D extends PSGraphics2D { + + OperatorCheckingPSGraphics2D(FontInfo fontInfo, final OperatorValidator validator) { + super(false, new PSGenerator(new NullOutputStream()) { + + @Override + public void writeln(String cmd) throws IOException { + validator.check(cmd); + } + + }); + } + } + + @Override + protected TextPainter createTextPainter(FontInfo fontInfo) { + return new PSTextPainter(fontInfo); + } + + @Override + protected Graphics2D createGraphics2D(FontInfo fontInfo, OperatorValidator validator) { + PSGraphics2D g2d = new OperatorCheckingPSGraphics2D(fontInfo, validator); + g2d.setGraphicContext(new GraphicContext()); + return g2d; + } + + @Test + public void testRotatedGlyph() throws Exception { + runTest("rotated-glyph.svg", new OperatorValidator() + .addOperatorMatch("Tm", "1 0 0 -1 40 110 Tm") + .addOperatorMatch("xshow", "(A)\n[0] xshow") + .addOperatorMatch("Tm", "0.70711 0.70711 0.70711 -0.70711 106.7 110 Tm") + .addOperatorMatch("xshow", "(B)\n[0] xshow") + .addOperatorMatch("Tm", "1 0 0 -1 173.39999 110 Tm") + .addOperatorMatch("xshow", "(C)\n[0] xshow")); + } + +} diff --git a/test/java/org/apache/fop/svg/baseline-shift.svg b/test/java/org/apache/fop/svg/baseline-shift.svg new file mode 100644 index 000000000..0f375b9af --- /dev/null +++ b/test/java/org/apache/fop/svg/baseline-shift.svg @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<svg width="150" height="60" xmlns="http://www.w3.org/2000/svg"> +<rect x="0" y="0" width="100%" height="100%" fill="none" stroke="black" stroke-width="2"/> +<g transform="translate(10, 40) scale(20) scale(0.001)"> +<text font-family="sans-serif" font-size="1000"> +AB<tspan baseline-shift="super">CD</tspan>EF<tspan baseline-shift="sub">GH</tspan>IJ +</text> +</g> +</svg> diff --git a/test/java/org/apache/fop/svg/dx-dy.svg b/test/java/org/apache/fop/svg/dx-dy.svg new file mode 100644 index 000000000..cfdc2de01 --- /dev/null +++ b/test/java/org/apache/fop/svg/dx-dy.svg @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg"> +<rect x="0" y="0" width="100%" height="100%" stroke="black" stroke-width="2" fill="none"/> +<g font-family="monospace" font-size="30"> + <text x="55" y="35">ABCDE</text> + <text x="55" y="75" dx="0 -4 22 -36 18" dy="0 10 -5 -15 10">ABCDE</text> +</g> +</svg> diff --git a/test/java/org/apache/fop/svg/font/BasicGlyphVectorTestCase.java b/test/java/org/apache/fop/svg/font/BasicGlyphVectorTestCase.java new file mode 100644 index 000000000..c6f062a84 --- /dev/null +++ b/test/java/org/apache/fop/svg/font/BasicGlyphVectorTestCase.java @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.awt.Rectangle; +import java.awt.font.GlyphMetrics; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.batik.gvt.font.GVTGlyphMetrics; +import org.apache.batik.gvt.font.GVTLineMetrics; + +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontMetrics; + +/** + * Tests all the methods of {@link FOPGVTGlyphVector} with a mocked font. + */ +public class BasicGlyphVectorTestCase extends FOPGVTGlyphVectorTest { + + private final int fontSize = 10000; + + @Before + public void createGlyphVector() { + FontMetrics metrics = mockFontMetrics(); + Font font = mockFont(metrics); + FOPGVTFont gvtFont = mockGVTFont(font); + CharacterIterator it = new StringCharacterIterator("ABC"); + glyphVector = new FOPGVTGlyphVector(gvtFont, it, null); + glyphVector.performDefaultLayout(); + } + + private FontMetrics mockFontMetrics() { + FontMetrics metrics = mock(FontMetrics.class); + when(metrics.getAscender(eq(fontSize))).thenReturn(8000000); + when(metrics.getDescender(eq(fontSize))).thenReturn(-4000000); + when(metrics.getWidth(eq(1), eq(fontSize))).thenReturn(10000000); + when(metrics.getBoundingBox(eq(1), eq(fontSize))).thenReturn( + new Rectangle(-1000000, -2000000, 3000000, 4000000)); + when(metrics.getWidth(eq(2), eq(fontSize))).thenReturn(11000000); + when(metrics.getBoundingBox(eq(2), eq(fontSize))).thenReturn( + new Rectangle(-5000000, -6000000, 7000000, 9000000)); + when(metrics.getWidth(eq(3), eq(fontSize))).thenReturn(12000000); + when(metrics.getBoundingBox(eq(3), eq(fontSize))).thenReturn( + new Rectangle(-9000000, -10000000, 11000000, 14000000)); + return metrics; + } + + private Font mockFont(FontMetrics metrics) { + Font font = mock(Font.class); + when(font.getFontMetrics()).thenReturn(metrics); + when(font.getFontSize()).thenReturn(fontSize); + when(font.mapChar(eq('A'))).thenReturn((char) 1); + when(font.mapChar(eq('B'))).thenReturn((char) 2); + when(font.mapChar(eq('C'))).thenReturn((char) 3); + return font; + } + + private FOPGVTFont mockGVTFont(Font font) { + FOPGVTFont gvtFont = mock(FOPGVTFont.class); + when(gvtFont.getFont()).thenReturn(font); + when(gvtFont.getLineMetrics(anyInt())).thenReturn( + new GVTLineMetrics(8, 0, null, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + return gvtFont; + } + + @Test + public void getGlyphCodeReturnsGlyphIndex() { + assertEquals(1, glyphVector.getGlyphCode(0)); + assertEquals(2, glyphVector.getGlyphCode(1)); + assertEquals(3, glyphVector.getGlyphCode(2)); + } + + @Test + public void testGetGlyphCodes() { + assertArrayEquals(new int[] {1, 2, 3}, glyphVector.getGlyphCodes(0, 3, null)); + assertArrayEquals(new int[] {2, 3}, glyphVector.getGlyphCodes(1, 2, null)); + } + + @Test + public void testGetGlyphMetrics() { + assertGlyphMetricsEqual(new GVTGlyphMetrics(10, 12, new Rectangle(-1, -2, 3, 4), GlyphMetrics.STANDARD), + glyphVector.getGlyphMetrics(0)); + assertGlyphMetricsEqual(new GVTGlyphMetrics(11, 12, new Rectangle(-5, -3, 7, 9), GlyphMetrics.STANDARD), + glyphVector.getGlyphMetrics(1)); + assertGlyphMetricsEqual(new GVTGlyphMetrics(12, 12, new Rectangle(-9, -4, 11, 14), GlyphMetrics.STANDARD), + glyphVector.getGlyphMetrics(2)); + } + + private void assertGlyphMetricsEqual(GVTGlyphMetrics expected, GVTGlyphMetrics actual) { + assertEquals(expected.getHorizontalAdvance(), actual.getHorizontalAdvance(), 0); + assertEquals(expected.getVerticalAdvance(), actual.getVerticalAdvance(), 0); + assertEquals(expected.getBounds2D(), actual.getBounds2D()); + assertEquals(expected.getLSB(), actual.getLSB(), 0); + assertEquals(expected.getRSB(), actual.getRSB(), 0); + assertEquals(expected.getType(), actual.getType()); + assertEquals(expected.isCombining(), actual.isCombining()); + assertEquals(expected.isComponent(), actual.isComponent()); + assertEquals(expected.isLigature(), actual.isLigature()); + assertEquals(expected.isStandard(), actual.isStandard()); + assertEquals(expected.isWhitespace(), actual.isWhitespace()); + } + + @Test + public void testGetGlyphPosition() { + assertEquals(new Point2D.Float(0, 0), glyphVector.getGlyphPosition(0)); + assertEquals(new Point2D.Float(10, 0), glyphVector.getGlyphPosition(1)); + assertEquals(new Point2D.Float(21, 0), glyphVector.getGlyphPosition(2)); + assertEquals(new Point2D.Float(33, 0), glyphVector.getGlyphPosition(3)); + } + + @Test + public void testGetGlyphPositions() { + float[] expectedPositions = new float[] {0, 0, 10, 0, 21, 0, 33, 0}; + assertArrayEquals(expectedPositions, glyphVector.getGlyphPositions(0, 4, null), 0); + assertArrayEquals(expectedPositions, glyphVector.getGlyphPositions(0, 4, new float[8]), 0); + } + + @Test + public void testGetGlyphOutline() { + assertEquals(new Rectangle(-1, -2, 3, 4), glyphVector.getGlyphOutline(0).getBounds()); + assertEquals(new Rectangle(5, -3, 7, 9), glyphVector.getGlyphOutline(1).getBounds()); + assertEquals(new Rectangle(12, -4, 11, 14), glyphVector.getGlyphOutline(2).getBounds()); + } + + @Test + public void testGetOutline() { + assertEquals(new Rectangle(-1, -4, 24, 14), glyphVector.getOutline().getBounds()); + } + + @Test + public void testGetLogicalBounds() { + assertEquals(new Rectangle(0, -8, 33, 12), glyphVector.getLogicalBounds()); + } + + @Test + public void testGetLogicalBoundsRotated() { + for (int i = 0; i < 3; i++) { + glyphVector.setGlyphTransform(i, new AffineTransform(0.7, 0.7, -0.7, 0.7, 0, 0)); + } + assertEquals(new Rectangle2D.Float(-2.8f, -5.6f, 37.8f, 16.8f), glyphVector.getLogicalBounds()); + } + + @Test + public void testGetBounds() { + assertEquals(new Rectangle(-1, -4, 24, 14), glyphVector.getBounds2D(null)); + } + + @Test + public void testGetGlyphVisualBounds() { + assertEquals(new Rectangle(-1, -2, 3, 4), glyphVector.getGlyphVisualBounds(0).getBounds()); + assertEquals(new Rectangle(5, -3, 7, 9), glyphVector.getGlyphVisualBounds(1).getBounds()); + assertEquals(new Rectangle(12, -4, 11, 14), glyphVector.getGlyphVisualBounds(2).getBounds()); + } + + @Test + public void testGetGlyphLogicalBounds() { + assertEquals(new Rectangle(0, -8, 10, 12), glyphVector.getGlyphLogicalBounds(0).getBounds()); + assertEquals(new Rectangle(10, -8, 11, 12), glyphVector.getGlyphLogicalBounds(1).getBounds()); + assertEquals(new Rectangle(21, -8, 12, 12), glyphVector.getGlyphLogicalBounds(2).getBounds()); + } + +} diff --git a/test/java/org/apache/fop/svg/font/FOPFontFamilyResolverTestCase.java b/test/java/org/apache/fop/svg/font/FOPFontFamilyResolverTestCase.java new file mode 100644 index 000000000..d14752b90 --- /dev/null +++ b/test/java/org/apache/fop/svg/font/FOPFontFamilyResolverTestCase.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.awt.FontFormatException; +import java.awt.GraphicsEnvironment; +import java.awt.font.FontRenderContext; +import java.awt.font.LineMetrics; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Collections; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.apache.batik.gvt.font.GVTFontFamily; +import org.apache.batik.gvt.font.GVTLineMetrics; + +import org.apache.fop.fonts.FontInfo; + +public class FOPFontFamilyResolverTestCase { + + private static FontInfo fontInfo; + + private FOPFontFamilyResolver resolver; + + @BeforeClass + public static void setUpFontInfo() { + fontInfo = new FontInfoBuilder() + .useDejaVuLGCSerif() + .useDroidSansMono() + .build(); + } + + @Before + public void createFontFamilyResolver() { + resolver = new FOPFontFamilyResolverImpl(fontInfo); + } + + @Test + public void testResolve() { + assertNull(resolver.resolve("Unavailable")); + assertNotNull(resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF)); + } + + @Test + public void testGetFamilyThatCanDisplay() { + GVTFontFamily family = resolver.getFamilyThatCanDisplay('\u0180'); + assertEquals(FontInfoBuilder.DEJAVU_LGC_SERIF, family.getFamilyName()); + family = resolver.getFamilyThatCanDisplay('\u02F3'); + assertEquals(FontInfoBuilder.DROID_SANS_MONO, family.getFamilyName()); + family = resolver.getFamilyThatCanDisplay('\u02DF'); + assertNull(family); + } + + @Test + public void testDeriveFont() { + FOPGVTFontFamily family = resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF); + FOPGVTFont font = family.deriveFont(10, Collections.emptyMap()); + assertEquals(10, font.getSize(), 0); + assertTrue(font.canDisplay('\u01F6')); + assertFalse(font.canDisplay('\u01F7')); + } + + @Test + @Ignore("FOP metrics don't match AWT, but not sure who is right and who is wrong") + public void testLineMetrics() throws FontFormatException, IOException { + FOPGVTFontFamily family = resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF); + FOPGVTFont font = family.deriveFont(10, Collections.emptyMap()); + GVTLineMetrics fopMetrics = font.getLineMetrics("", null); + LineMetrics awtMetrics = getAWTLineMetrics(); + printDifference("Ascent", awtMetrics.getAscent(), fopMetrics.getAscent()); + printDifference("Descent", awtMetrics.getDescent(), fopMetrics.getDescent()); + printDifference("Height", awtMetrics.getHeight(), fopMetrics.getHeight()); + printDifference("Leading", awtMetrics.getLeading(), fopMetrics.getLeading()); + printDifference("StrikethroughOffset", awtMetrics.getStrikethroughOffset(), + fopMetrics.getStrikethroughOffset()); + printDifference("StrikethroughThickness", awtMetrics.getStrikethroughThickness(), + fopMetrics.getStrikethroughThickness()); + printDifference("UnderlineOffset", awtMetrics.getUnderlineOffset(), + fopMetrics.getUnderlineOffset()); + printDifference("UnderlineThickness", awtMetrics.getUnderlineThickness(), + fopMetrics.getUnderlineThickness()); + } + + private LineMetrics getAWTLineMetrics() throws FontFormatException, IOException { + File fontFile = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); + java.awt.Font awtFont = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, fontFile).deriveFont(10f); + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + BufferedImage dummyImage = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_RGB); + FontRenderContext frc = ge.createGraphics(dummyImage).getFontRenderContext(); + LineMetrics awtMetrics = awtFont.getLineMetrics("ABC", frc); + return awtMetrics; + } + + private void printDifference(String value, float awt, float fop) { + System.out.println(String.format("%22s AWT: %10f FOP: %10f Difference: %.2f%%", value, awt, fop, + (fop - awt) / awt * 100)); + } + +} diff --git a/test/java/org/apache/fop/svg/font/FOPGVTFontTestCase.java b/test/java/org/apache/fop/svg/font/FOPGVTFontTestCase.java new file mode 100644 index 000000000..b27dac5b2 --- /dev/null +++ b/test/java/org/apache/fop/svg/font/FOPGVTFontTestCase.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.text.StringCharacterIterator; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.fop.fonts.Font; + +public class FOPGVTFontTestCase { + + private FOPGVTFont font; + + @Before + public void createFont() { + Font f = mock(Font.class); + when(f.hasChar(eq((char) 0))).thenReturn(false); + when(f.hasChar(eq((char) 1))).thenReturn(true); + font = new FOPGVTFont(f, null); + } + + @Test + public void testCanDisplayUpTo() { + char[] text = new char[] {1, 1, 1}; + testCanDisplayUpToVariants(text, -1, 0, 3); + testCanDisplayUpToVariants(text, -1, 1, 3); + text = new char[] {1, 1, 0, 1}; + testCanDisplayUpToVariants(text, 2, 0, 4); + testCanDisplayUpToVariants(text, 2, 1, 4); + testCanDisplayUpToVariants(text, 2, 2, 4); + testCanDisplayUpToVariants(text, -1, 3, 4); + testCanDisplayUpToVariants(text, -1, 1, 2); + } + + @Test + public void testCanDisplayUpToString() { + assertEquals(-1, font.canDisplayUpTo(new String(new char[] {1, 1, 1}))); + assertEquals(0, font.canDisplayUpTo(new String(new char[] {0, 1, 1}))); + assertEquals(1, font.canDisplayUpTo(new String(new char[] {1, 0, 1}))); + assertEquals(2, font.canDisplayUpTo(new String(new char[] {1, 1, 0}))); + } + + private void testCanDisplayUpToVariants(char[] text, int expected, int start, int limit) { + assertEquals(expected, font.canDisplayUpTo(text, start, limit)); + assertEquals(expected, font.canDisplayUpTo(new StringCharacterIterator(new String(text)), start, limit)); + } +} diff --git a/test/java/org/apache/fop/svg/font/FOPGVTGlyphVectorTest.java b/test/java/org/apache/fop/svg/font/FOPGVTGlyphVectorTest.java new file mode 100644 index 000000000..0995ab4df --- /dev/null +++ b/test/java/org/apache/fop/svg/font/FOPGVTGlyphVectorTest.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + + +public abstract class FOPGVTGlyphVectorTest { + + protected FOPGVTGlyphVector glyphVector; + +} diff --git a/test/java/org/apache/fop/svg/font/FontInfoBuilder.java b/test/java/org/apache/fop/svg/font/FontInfoBuilder.java new file mode 100644 index 000000000..c9346588c --- /dev/null +++ b/test/java/org/apache/fop/svg/font/FontInfoBuilder.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.fop.apps.io.InternalResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; +import org.apache.fop.fonts.EmbeddingMode; +import org.apache.fop.fonts.EncodingMode; +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontMetrics; +import org.apache.fop.fonts.truetype.OFFontLoader; + +class FontInfoBuilder { + + public static final String DEJAVU_LGC_SERIF = "DejaVu LGC Serif"; + + public static final String DROID_SANS_MONO = "Droid Sans Mono"; + + private static final boolean USE_ADVANCED_BY_DEFAULT = true; + + private FontInfo fontInfo; + + private int fontKey; + + public FontInfoBuilder() { + reset(); + } + + private void reset() { + fontInfo = new FontInfo(); + fontKey = 1; + } + + public FontInfoBuilder useDejaVuLGCSerif() { + return useDejaVuLGCSerif(USE_ADVANCED_BY_DEFAULT); + } + + public FontInfoBuilder useDejaVuLGCSerif(boolean useAdvanced) { + try { + return useFont(DEJAVU_LGC_SERIF, "DejaVuLGCSerif.ttf", useAdvanced); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public FontInfoBuilder useDroidSansMono() { + return useDroidSansMono(USE_ADVANCED_BY_DEFAULT); + } + + public FontInfoBuilder useDroidSansMono(boolean useAdvanced) { + try { + return useFont(DROID_SANS_MONO, "DroidSansMono.ttf", useAdvanced); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private FontInfoBuilder useFont(String fontName, String filename, boolean useAdvanced) + throws IOException, URISyntaxException { + URI baseURI = new File("test/resources/fonts/ttf").toURI(); + InternalResourceResolver resolver = ResourceResolverFactory.createDefaultInternalResourceResolver(baseURI); + OFFontLoader fontLoader = new OFFontLoader(new URI(filename), null, true, + EmbeddingMode.AUTO, EncodingMode.AUTO, true, useAdvanced, resolver); + FontMetrics font = fontLoader.getFont(); + registerFont(font, "F" + fontKey++, fontName); + return this; + } + + private void registerFont(FontMetrics font, String key, String familyName) { + fontInfo.addMetrics(key, font); + fontInfo.addFontProperties(key, familyName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + } + + public FontInfo build() { + FontInfo fontInfo = this.fontInfo; + reset(); + return fontInfo; + } +} diff --git a/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java b/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java new file mode 100644 index 000000000..5c1fb2c86 --- /dev/null +++ b/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.svg.font; + +import java.util.Collections; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +import org.apache.fop.fonts.FontInfo; + +/** + * Specifically tests glyph positioning from a real font. + */ +public class GlyphLayoutTestCase extends FOPGVTGlyphVectorTest { + + /** + * Glyph positioning using the legacy kern table. + */ + @Test + public void testBasicGlyphPositioning() throws Exception { + testGlyphLayout(false); + } + + /** + * Glyph positioning using GPOS sub-tables. + */ + @Test + public void testAdvancedGlyphPositioning() throws Exception { + testGlyphLayout(true); + } + + private void testGlyphLayout(boolean useAdvanced) { + FOPGVTFont font = loadFont(useAdvanced); + glyphVector = (FOPGVTGlyphVector) font.createGlyphVector(null, "L\u201DP,V.F,A\u2019LT."); + glyphVector.performDefaultLayout(); + // Values in font units (unitsPerEm = 2048), glyph width - kern + int[] widths = { + /* L */ 1360 - 491, + /* " */ 1047, + /* P */ 1378 - 415, + /* , */ 651, + /* V */ 1479 - 358, + /* . */ 651, + /* F */ 1421 - 319, + /* , */ 651, + /* A */ 1479 - 301, + /* ' */ 651, + /* L */ 1360 - 167, + /* T */ 1366 - 301, + /* . */ 651}; + checkGlyphPositions(13, widths); + } + + private FOPGVTFont loadFont(boolean useAdvanced) { + FontInfo fontInfo = new FontInfoBuilder().useDejaVuLGCSerif(useAdvanced).build(); + FOPFontFamilyResolver resolver = new FOPFontFamilyResolverImpl(fontInfo); + FOPGVTFontFamily family = resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF); + return family.deriveFont(1000, Collections.emptyMap()); + } + + private void checkGlyphPositions(int expectedGlyphCount, int[] widths) { + assertEquals(expectedGlyphCount, glyphVector.getNumGlyphs()); + float[] positions = new float[2 * (widths.length + 1)]; + for (int i = 0, n = 2; i < widths.length; i++, n += 2) { + positions[n] = positions[n - 2] + widths[i] / 2.048f; + } + for (int i = 0; i <= widths.length; i++) { + assertEquals(positions[2 * i], glyphVector.getGlyphPosition(i).getX(), 3); + } + } + +} diff --git a/test/java/org/apache/fop/svg/glyph-orientation.svg b/test/java/org/apache/fop/svg/glyph-orientation.svg new file mode 100644 index 000000000..4900a3b02 --- /dev/null +++ b/test/java/org/apache/fop/svg/glyph-orientation.svg @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<svg width="100" height="140" xmlns="http://www.w3.org/2000/svg"> +<rect x="0" y="0" width="100%" height="100%" fill="none" stroke="black" stroke-width="2"/> +<g transform="translate(10) scale(20) scale(0.001) translate(0, 1000)" + font-family="sans-serif" font-size="1000"> + <text x="1000" writing-mode="tb">ABCD</text> + <text x="2500" writing-mode="tb" glyph-orientation-vertical="0">EFGH</text> + <text x="0" y="5000" glyph-orientation-horizontal="270">IJKL</text> +</g> +</svg> diff --git a/test/java/org/apache/fop/svg/rotated-glyph.svg b/test/java/org/apache/fop/svg/rotated-glyph.svg new file mode 100644 index 000000000..8b942905e --- /dev/null +++ b/test/java/org/apache/fop/svg/rotated-glyph.svg @@ -0,0 +1,5 @@ +<?xml version="1.0"?> +<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg"> +<rect x="0" y="0" width="100%" height="100%" fill="none" stroke="black" stroke-width="2"/> +<text font-family="Helvetica" font-size="100" x="40" y="110" rotate="0 45 0">ABC</text> +</svg> diff --git a/test/java/org/apache/fop/svg/spacing.svg b/test/java/org/apache/fop/svg/spacing.svg new file mode 100644 index 000000000..943ab1d04 --- /dev/null +++ b/test/java/org/apache/fop/svg/spacing.svg @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<svg width="150" height="200" xmlns="http://www.w3.org/2000/svg"> +<rect x="0" y="0" width="100%" height="100%" stroke="black" stroke-width="2" fill="none"/> +<g transform="translate(10) scale(40) scale(0.001) translate(0, 1000)" + font-family="sans-serif" font-size="1000"> + <g transform=""> + <text>VAV</text> + <line x1="667" y1="-818" x2="667" y2="100" stroke-width="10" stroke="blue"/> + </g> + <g transform="translate(0, 1000)"> + <text kerning="0">VAV</text> + <line x1="667" y1="-818" x2="667" y2="100" stroke-width="10" stroke="blue"/> + </g> + <g transform="translate(0, 2000)"> + <text letter-spacing="100">VAV</text> + </g> + <g transform="translate(0, 3000)"> + <text word-spacing="500">ab cd</text> + </g> +</g> +</svg> diff --git a/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java b/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java index 42ca8dee6..d8813c3bc 100644 --- a/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java +++ b/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java @@ -19,10 +19,10 @@ package org.apache.fop.text.linebreak; -import static org.junit.Assert.assertTrue; - import org.junit.Test; +import static org.junit.Assert.assertTrue; + /** * JUnit test case for the LineBreakStatus class diff --git a/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java b/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java index 015c1846f..5fc5c7d50 100644 --- a/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java +++ b/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java @@ -19,10 +19,10 @@ package org.apache.fop.text.linebreak; -import static org.junit.Assert.assertEquals; - import org.junit.Test; +import static org.junit.Assert.assertEquals; + /** * TODO add javadoc * diff --git a/test/java/org/apache/fop/threading/FOProcessorImpl.java b/test/java/org/apache/fop/threading/FOProcessorImpl.java index 04fed19ba..721830aee 100644 --- a/test/java/org/apache/fop/threading/FOProcessorImpl.java +++ b/test/java/org/apache/fop/threading/FOProcessorImpl.java @@ -81,8 +81,8 @@ public class FOProcessorImpl extends AbstractLogEnabled } } - /** {@inheritDoc} - * @throws URISyntaxException + /** {@inheritDoc} + * @throws URISyntaxException * @throws SAXException */ public void process(Source src, Templates templates, OutputStream out) throws java.io.IOException, URISyntaxException, SAXException { diff --git a/test/java/org/apache/fop/threading/Main.java b/test/java/org/apache/fop/threading/Main.java index 7ff0cec4f..d18ae405a 100644 --- a/test/java/org/apache/fop/threading/Main.java +++ b/test/java/org/apache/fop/threading/Main.java @@ -32,7 +32,10 @@ import org.apache.avalon.framework.logger.ConsoleLogger; /** * Starter class for the multi-threading testbed. */ -public class Main { +public final class Main { + + private Main() { + } private static void prompt() throws IOException { BufferedReader in = new BufferedReader(new java.io.InputStreamReader(System.in)); diff --git a/test/java/org/apache/fop/traits/BorderPropsTestCase.java b/test/java/org/apache/fop/traits/BorderPropsTestCase.java index ec93d708e..692e3059f 100644 --- a/test/java/org/apache/fop/traits/BorderPropsTestCase.java +++ b/test/java/org/apache/fop/traits/BorderPropsTestCase.java @@ -23,14 +23,14 @@ import java.awt.Color; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives; import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; import org.apache.fop.fo.Constants; import org.apache.fop.util.ColorUtil; -import static org.junit.Assert.assertEquals; - /** * Tests the BorderProps class. */ @@ -67,7 +67,7 @@ public class BorderPropsTestCase { Color col = new Color(1.0f, 1.0f, 0.5f, 1.0f); //Normalize: Avoid false alarms due to color conversion (rounding) col = ColorUtil.parseColorString(null, ColorUtil.colorToString(col)); - for(BorderProps.Mode mode : BorderProps.Mode.values()) { + for (BorderProps.Mode mode : BorderProps.Mode.values()) { BorderProps sut = BorderProps.makeRectangular(Constants.EN_SOLID, 10, col, mode); testSerialization(sut); sut = new BorderProps(Constants.EN_SOLID, 10, 4, 3, col, mode); diff --git a/test/java/org/apache/fop/traits/MinOptMaxTestCase.java b/test/java/org/apache/fop/traits/MinOptMaxTestCase.java index 73465fdcc..ba6862785 100644 --- a/test/java/org/apache/fop/traits/MinOptMaxTestCase.java +++ b/test/java/org/apache/fop/traits/MinOptMaxTestCase.java @@ -19,13 +19,13 @@ package org.apache.fop.traits; +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import org.junit.Test; - /** * Tests the {@link MinOptMax} class. */ diff --git a/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java b/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java index c4b9446ac..5e75f2563 100644 --- a/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java +++ b/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java @@ -19,15 +19,16 @@ package org.apache.fop.util; -import static org.junit.Assert.assertEquals; - import java.util.Map; -import org.apache.fop.events.model.EventSeverity; -import org.apache.fop.util.text.AdvancedMessageFormat; import org.junit.Test; import org.xml.sax.helpers.LocatorImpl; +import static org.junit.Assert.assertEquals; + +import org.apache.fop.events.model.EventSeverity; +import org.apache.fop.util.text.AdvancedMessageFormat; + /** * Tests for EventFormatter. */ diff --git a/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java b/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java index 3afcc3a2e..8bda99785 100644 --- a/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java +++ b/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java @@ -19,8 +19,6 @@ package org.apache.fop.util; -import static org.junit.Assert.assertEquals; - import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; @@ -31,13 +29,18 @@ import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + import org.apache.commons.io.IOUtils; -import org.apache.fop.util.bitmap.BitmapImageUtil; -import org.apache.fop.util.bitmap.MonochromeBitmapConverter; + import org.apache.xmlgraphics.image.writer.ImageWriterUtil; import org.apache.xmlgraphics.util.WriterOutputStream; import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream; -import org.junit.Test; + +import org.apache.fop.util.bitmap.BitmapImageUtil; +import org.apache.fop.util.bitmap.MonochromeBitmapConverter; /** * Tests {@link BitmapImageUtil}. diff --git a/test/java/org/apache/fop/util/ColorUtilTestCase.java b/test/java/org/apache/fop/util/ColorUtilTestCase.java index 6e65004a3..c86ebbeac 100644 --- a/test/java/org/apache/fop/util/ColorUtilTestCase.java +++ b/test/java/org/apache/fop/util/ColorUtilTestCase.java @@ -26,6 +26,11 @@ import java.net.URI; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import org.apache.xmlgraphics.java2d.color.ColorSpaces; import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives; import org.apache.xmlgraphics.java2d.color.NamedColorSpace; @@ -34,11 +39,6 @@ import org.apache.xmlgraphics.java2d.color.RenderingIntent; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - /** * Tests the ColorUtil class. */ diff --git a/test/java/org/apache/fop/util/DigestFilter.java b/test/java/org/apache/fop/util/DigestFilter.java index 94e8d67d2..9e62fdc1c 100644 --- a/test/java/org/apache/fop/util/DigestFilter.java +++ b/test/java/org/apache/fop/util/DigestFilter.java @@ -95,9 +95,6 @@ public class DigestFilter extends XMLFilterImpl { super.endDocument(); } - /* (non-Javadoc) - * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) - */ public void startElement( String url, String localName, diff --git a/test/java/org/apache/fop/util/ElementListUtilsTestCase.java b/test/java/org/apache/fop/util/ElementListUtilsTestCase.java index 342488a93..5e4f38b0b 100644 --- a/test/java/org/apache/fop/util/ElementListUtilsTestCase.java +++ b/test/java/org/apache/fop/util/ElementListUtilsTestCase.java @@ -19,17 +19,18 @@ package org.apache.fop.util; +import java.util.LinkedList; + +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import java.util.LinkedList; - import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.KnuthPenalty; -import org.junit.Test; /** * Test class for ElementListUtils. diff --git a/test/java/org/apache/fop/util/LanguageTagsTestCase.java b/test/java/org/apache/fop/util/LanguageTagsTestCase.java index f7383c720..91861dcc6 100644 --- a/test/java/org/apache/fop/util/LanguageTagsTestCase.java +++ b/test/java/org/apache/fop/util/LanguageTagsTestCase.java @@ -19,12 +19,12 @@ package org.apache.fop.util; -import static org.junit.Assert.assertEquals; - import java.util.Locale; import org.junit.Test; +import static org.junit.Assert.assertEquals; + /** * Tests {@link LanguageTags}. */ diff --git a/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java b/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java index 26cfa4406..60aa16d83 100644 --- a/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java +++ b/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java @@ -19,15 +19,15 @@ package org.apache.fop.util; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + /** * Tests for XMLResourceBundle. */ diff --git a/test/java/org/apache/fop/visual/BitmapComparator.java b/test/java/org/apache/fop/visual/BitmapComparator.java index e0c1d5bd4..f2157176b 100644 --- a/test/java/org/apache/fop/visual/BitmapComparator.java +++ b/test/java/org/apache/fop/visual/BitmapComparator.java @@ -30,11 +30,12 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import org.apache.commons.io.IOUtils; + import org.apache.batik.ext.awt.image.GraphicsUtil; import org.apache.batik.ext.awt.image.renderable.Filter; import org.apache.batik.ext.awt.image.spi.ImageTagRegistry; import org.apache.batik.util.ParsedURL; -import org.apache.commons.io.IOUtils; /** * Helper class to visually compare two bitmap images. @@ -45,7 +46,11 @@ import org.apache.commons.io.IOUtils; * <p> * TODO Move as utility class to XML Graphics Commons when possible */ -public class BitmapComparator { +public final class BitmapComparator { + + + private BitmapComparator() { + } /** * Builds a new BufferedImage that is the difference between the two input images @@ -79,15 +84,14 @@ public class BitmapComparator { int w = ref.getWidth(); int h = ref.getHeight(); - int y, i, val; int [] refPix = null; int [] genPix = null; - for (y = 0; y < h; y++) { - refPix = refWR.getPixels (0, y, w, 1, refPix); - genPix = genWR.getPixels (0, y, w, 1, genPix); - for (i = 0; i < refPix.length; i++) { + for (int y = 0; y < h; y++) { + refPix = refWR.getPixels(0, y, w, 1, refPix); + genPix = genWR.getPixels(0, y, w, 1, genPix); + for (int i = 0; i < refPix.length; i++) { // val = ((genPix[i] - refPix[i]) * 5) + 128; - val = ((refPix[i] - genPix[i]) * 10) + 128; + int val = ((refPix[i] - genPix[i]) * 10) + 128; if ((val & 0xFFFFFF00) != 0) { if ((val & 0x80000000) != 0) { val = 0; diff --git a/test/java/org/apache/fop/visual/ConvertUtils.java b/test/java/org/apache/fop/visual/ConvertUtils.java index e83322f90..aa4dadf47 100644 --- a/test/java/org/apache/fop/visual/ConvertUtils.java +++ b/test/java/org/apache/fop/visual/ConvertUtils.java @@ -27,7 +27,10 @@ import org.apache.commons.logging.Log; /** * Utilities for converting files with external converters. */ -public class ConvertUtils { +public final class ConvertUtils { + + private ConvertUtils() { + } /** * Calls an external converter application (GhostScript, for example). diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml index 5208fa91d..b96ee1b77 100644 --- a/test/layoutengine/disabled-testcases.xml +++ b/test/layoutengine/disabled-testcases.xml @@ -91,16 +91,15 @@ NullPointerException.</description> </testcase> <testcase> - <name>inline-container is not implemented, yet.</name> - <file>inline-container_block_nested.xml</file> - <description>inline-container is not implemented, yet. Content of an - inline-container will get swallowed. The test case contains no checks.</description> + <name>Keeps on inline-container are not implemented, yet.</name> + <file>inline-container_keeps.xml</file> + <description>The keep-with-previous and keep-with-next properties have not been implemented on + inline-container yet. They will be treated as if they had the value "auto".</description> </testcase> <testcase> - <name>inline-container is not implemented, yet.</name> + <name>Borders and padding inline-container are not implemented, yet.</name> <file>inline-container_border_padding.xml</file> - <description>inline-container is not implemented, yet. Content of an - inline-container will get swallowed.</description> + <description>Borders and paddings on an inline-container will be ignored.</description> </testcase> <testcase> <name>inline letter-spacing</name> diff --git a/test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml b/test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml new file mode 100644 index 000000000..3e696a696 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml @@ -0,0 +1,244 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that the alignment-adjust property on inline-container behaves properly. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="170pt" page-width="220pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="before-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="before-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="text-before-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="text-before-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="after-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="after-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="text-after-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="text-after-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="middle":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="middle"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="central":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="central"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="ideographic":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="ideographic"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="alphabetic":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="alphabetic"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="hanging":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="hanging"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="mathematical":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="mathematical"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="30pt":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="30pt"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="10%":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="-10%" dominant-baseline="text-before-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + </fo:root> + </fo> + + <checks> + + <!-- before-edge --> + <eval expected="37416" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- text-before-edge --> + <eval expected="37416" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- after-edge --> + <eval expected="31284" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="20184" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- text-after-edge --> + <eval expected="31284" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="20184" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- middle --> + <eval expected="28800" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="5784" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- central --> + <eval expected="28800" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="5784" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- ideographic --> + <eval expected="28800" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="11544" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- alphabetic --> + <eval expected="28800" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="8664" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- hanging --> + <eval expected="31656" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="2856" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- mathematical --> + <eval expected="28800" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="5784" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- 30pt --> + <eval expected="49764" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="38664" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- 10% --> + <eval expected="38856" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="10056" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml b/test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml new file mode 100644 index 000000000..53b9be0a9 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that the alignment-baseline property on inline-container behaves properly. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="170pt" page-width="220pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-baseline="before-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-baseline="before-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-baseline="central":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-baseline="central"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + </fo:root> + </fo> + + <checks> + + <!-- before-edge --> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- central --> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="8850" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_alignment.xml b/test/layoutengine/standard-testcases/inline-container_alignment.xml new file mode 100644 index 000000000..153d9a9c4 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_alignment.xml @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that the inline-container is properly aligned with the parent area. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="320pt" page-width="220pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>By default the alignment is with the baseline of the first descendant + line-area.</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:block font-size="20pt">Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:block space-before="20pt" space-before.conditionality="retain"> + <fo:block-container space-before="10pt" space-before.conditionality="retain" + border="4pt solid" padding="2pt" start-indent="6pt" end-indent="6pt"> + <fo:block font-size="20pt" start-indent="0" end-indent="0">Inside the + inline-container.</fo:block> + </fo:block-container> + </fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>This inline-container has no line-area descendant. The after edge of its + allocation rectangle should be aligned with the baseline.</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:block border="6pt solid" padding="2pt" start-indent="8pt" end-indent="8pt"/> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>The first line-area descendant is in fo:list-item-body.</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:list-block provisional-distance-between-starts="10pt" + provisional-label-separation="5pt"> + <fo:list-item> + <fo:list-item-label end-indent="label-end()"> + <fo:block/> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block> + <fo:block font-size="8pt">List item</fo:block> + </fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>This inline-container contains a block that contains an inline that contains a + block.</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:block><fo:inline><fo:block>inline</fo:block></fo:inline></fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <!-- Page sequence 1 --> + <eval expected="72000" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/> + <!-- + The font used is Helvetica, ascender 718, descender −207. + Default font size is 12pt => baseline offset = 718 * 12 = 8616mpt + Default line height is 1.2 * font-size + => space-before = (line-height − (ascender − descender) * font-size) / 2 + = (1.2 * 12000 − (718 + 207) * 12) / 2 + = 1650 + At font size 20, the distance between the before-edge of the inline-container’s child block + area and the first line area’s baseline is space-before + baseline-offset = 2750 + 14360 = 17110 + So the word "Before:" must be offset by 17110 − 8616 = 8494 + --> + <eval expected="Before: " xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]"/> + <eval expected="8494" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + + <eval expected="72000" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <eval expected=" After the" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[2]"/> + <eval expected="8494" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[2]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[2]/@baseline"/> + + <!-- Page sequence 2 --> + <eval expected="34494" xpath="//pageSequence[2]//flow/block/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block/lineArea[2]/text[1]/@baseline"/> + <eval expected="104000" xpath="//pageSequence[2]//flow/block/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[2]//flow/block/lineArea[2]/viewport/@offset"/> + + <!-- Page sequence 3 --> + <!-- bpd = max(text ascent, ascent of inline-container) + text descent + = 16000 + 207 * 12 --> + <eval expected="18484" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="7384" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="16000" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- Page sequence 4 --> + <eval expected="11372" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="9600" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="1772" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- Page sequence 5 --> + <eval expected="14400" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="1650" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="14400" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@offset"/> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_basic.xml b/test/layoutengine/standard-testcases/inline-container_basic.xml new file mode 100644 index 000000000..b2dfcc6e5 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_basic.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Test for a basic implementation of fo:inline-container. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="320pt" page-width="420pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="80pt" height="50pt"> + <fo:block>Text inside inline-container.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <!-- The inline-container’s area is there, at the right place --> + <eval expected="viewport" xpath="local-name(//flow/block/lineArea/*[position()=2])"/> + <!-- It has the right properties --> + <eval expected="true" xpath="//viewport/@is-viewport-area"/> + <eval expected="80000" xpath="//viewport/@ipd"/> + <eval expected="50000" xpath="//viewport/@bpd"/> + <eval expected="1" xpath="count(//viewport/*)"/> + <eval expected="container" xpath="local-name(//viewport/*)"/> + <!-- Its content is there too --> + <eval expected="1" xpath="count(//container/block)"/> + <eval expected="80000" xpath="//container/block/@ipd"/> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_block_nested.xml b/test/layoutengine/standard-testcases/inline-container_block_nested.xml deleted file mode 100644 index cf4ebf486..000000000 --- a/test/layoutengine/standard-testcases/inline-container_block_nested.xml +++ /dev/null @@ -1,65 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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$ --> -<testcase> - <info> - <p> - This test checks nested blocks with inline-containers and indents. - </p> - </info> - <fo> - <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg"> - <fo:layout-master-set> - <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in"> - <fo:region-body/> - </fo:simple-page-master> - </fo:layout-master-set> - <fo:page-sequence master-reference="normal" white-space-collapse="true"> - <fo:flow flow-name="xsl-region-body"> - <fo:block margin-left="12pt">outer block - <fo:inline-container start-indent="18pt"> - <fo:block margin-left="13pt">inner block</fo:block> - </fo:inline-container> - </fo:block> - </fo:flow> - </fo:page-sequence> - </fo:root> - </fo> - <checks> - <!-- First block, no gap --> - <!--eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-start"/> - <eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-end"/> - <eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-before"/> - <eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-after"/> - <eval expected="5000 5000 5000 5000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@bap"/> - <eval expected="350000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@ipd"/> - <eval expected="360000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@ipda"/> - <eval expected="24400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@bpd"/> - <eval expected="34400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@bpda"/--> - <!-- Nested block of first block --> - <!--eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-start"/> - <eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-end"/> - <eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-before"/> - <eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-after"/> - <eval expected="5000 5000 5000 5000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@bap"/> - <eval expected="340000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@ipd"/> - <eval expected="350000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@ipda"/> - <eval expected="14400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@bpd"/> - <eval expected="24400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@bpda"/--> - </checks> -</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_bpd.xml b/test/layoutengine/standard-testcases/inline-container_bpd.xml new file mode 100644 index 000000000..8f808c030 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_bpd.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that block-progression-dimension on fo:inline-container is properly handled. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-size="8pt" line-height="10pt"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="60pt"> + <fo:block>This text inside inline-container should fit on four lines.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="70pt" height="35pt" overflow="hidden"> + <fo:block>This text overflows the inline-container in the + block-progression-direction.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="80pt"> + <fo:block space-after="10pt">Block 1</fo:block> + <fo:block space-before="20pt" space-after="10pt" + space-after.conditionality="retain">Block 2</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <eval expected="40000" xpath="//pageSequence[1]//viewport/@bpd"/> + + <eval expected="35000" xpath="//pageSequence[2]//viewport/@bpd"/> + <true xpath="//pageSequence[2]//viewport/@clip"/> + + <eval expected="50000" xpath="//pageSequence[3]//viewport/@bpd"/> + </checks> + + <event-checks> + <event key="viewportBPDOverflow" elementName="fo:inline-container" amount="15000" clip="true"/> + </event-checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml b/test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml new file mode 100644 index 000000000..402eb806d --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that the dominant-baseline property on inline-container behaves properly. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="170pt" page-width="220pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">dominant-baseline="alphabetic":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="baseline"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">dominant-baseline="central":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="baseline" dominant-baseline="central"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + </fo:root> + </fo> + + <checks> + + <!-- alphabetic --> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="8664" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- central --> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="5784" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_ipd-auto.xml b/test/layoutengine/standard-testcases/inline-container_ipd-auto.xml new file mode 100644 index 000000000..c19544809 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_ipd-auto.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + When inline-progression-dimension has been left to auto on fo:inline-container, fall back to + the IPD of the nearest ancestor reference-area. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container height="20pt"> + <fo:block>Text inside inline-container.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block-container space-before="10pt" start-indent="100pt" width="100pt"> + <fo:block start-indent="0"> + Before: <fo:inline-container> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After. + </fo:block> + </fo:block-container> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <eval expected="3" xpath="count(//pageSequence[1]//flow/block/lineArea)"/> + <eval expected="300000" xpath="//pageSequence[1]//flow/block/lineArea[2]/viewport/@ipd"/> + <eval expected="3" xpath="count(//pageSequence[2]//flow/block/block/block/lineArea)"/> + <eval expected="100000" xpath="//pageSequence[2]//flow/block/block/block/lineArea[2]/viewport/@ipd"/> + </checks> + + <event-checks> + <event key="inlineContainerAutoIPDNotSupported" fallback="300.0"/> + <event key="inlineContainerAutoIPDNotSupported" fallback="100.0"/> + </event-checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_ipd-percent.xml b/test/layoutengine/standard-testcases/inline-container_ipd-percent.xml new file mode 100644 index 000000000..aa681d134 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_ipd-percent.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that percentage values for the dimensions of an fo:inline-container are resolved + properly. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-size="8pt" line-height="10pt"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="50%" height="50%"> + <fo:block>Text inside inline-container.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block-container space-before="10pt" start-indent="50pt" width="200pt"> + <fo:block start-indent="0"> + Before: <fo:inline-container width="30%" height="30%"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After. + </fo:block> + </fo:block-container> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <eval expected="150000" xpath="//pageSequence[1]//flow/block/lineArea/viewport/@ipd"/> + <eval expected="10000" xpath="//pageSequence[1]//flow/block/lineArea/viewport/@bpd"/> + <eval expected="60000" xpath="//pageSequence[2]//flow/block/block/block/lineArea/viewport/@ipd"/> + <eval expected="20000" xpath="//pageSequence[2]//flow/block/block/block/lineArea/viewport/@bpd"/> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_keeps.xml b/test/layoutengine/standard-testcases/inline-container_keeps.xml new file mode 100644 index 000000000..e946f13f3 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_keeps.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Test for keeps on fo:inline-container. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>This inline-container must be kept with the word before: <fo:inline-container + id="inline-container" width="100pt" keep-with-previous.within-line="always" + background-color="#F0F0F0"> + <fo:block>Inline-container</fo:block> + </fo:inline-container></fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <eval expected="before: " xpath="//pageSequence[1]//flow/block/lineArea[2]/text[1]"/> + <eval expected="inline-container" xpath="//pageSequence[1]//flow/block/lineArea[2]/viewport/@prod-id"/> + </checks> +</testcase> diff --git a/test/layoutengine/testcase2checks.xsl b/test/layoutengine/testcase2checks.xsl index ae3a8fe72..25dfcc810 100644 --- a/test/layoutengine/testcase2checks.xsl +++ b/test/layoutengine/testcase2checks.xsl @@ -25,6 +25,7 @@ <checks> <xsl:apply-templates select="checks"/> <xsl:apply-templates select="if-checks"/> + <xsl:apply-templates select="event-checks"/> </checks> </xsl:template> @@ -40,7 +41,13 @@ <xsl:copy-of select="*"/> </if-checks> </xsl:template> - + +<xsl:template match="event-checks"> + <event-checks> + <xsl:copy-of select="*"/> + </event-checks> +</xsl:template> + <xsl:template match="text()" /> </xsl:stylesheet> diff --git a/test/xml/pdf-a/svg-transparency.fo b/test/xml/pdf-a/svg-transparency.fo new file mode 100644 index 000000000..922416fbc --- /dev/null +++ b/test/xml/pdf-a/svg-transparency.fo @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Gladiator"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="420pt" page-width="620pt" margin="10pt"> + <fo:region-body display-align="center"/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body" text-align="center"> + <fo:block font-size="20pt">RGB Circles</fo:block> + <fo:block><fo:instream-foreign-object> + <svg xmlns="http://www.w3.org/2000/svg" width="300" height="286.6"> + <g style="fill-opacity:0.7; stroke:black; stroke-width:3" + transform="translate(0, 286.6) scale(1, -1) translate(100, 100)"> + <circle cx="50" cy="86.6" r="80" style="fill:red;"/> + <circle cx="0" cy="0" r="80" style="fill:green;"/> + <circle cx="100" cy="0" r="80" style="fill:blue;"/> + </g> + </svg> + </fo:instream-foreign-object></fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> |