Parcourir la source

Bugzilla #54037: Issue a warning when accessibility is enabled for PDF output and language information is missing


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1400890 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-2_0
Vincent Hennebert il y a 11 ans
Parent
révision
eb45e0a465

+ 37
- 2
src/java/org/apache/fop/area/Block.java Voir le fichier

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

package org.apache.fop.area;

import java.util.Locale;


// block areas hold either more block areas or line
// areas can also be used as a block spacer
@@ -63,8 +65,9 @@ public class Block extends BlockParent {
/** if true, allow BPD update */
protected transient boolean allowBPDUpdate = true;

// a block with may contain the dominant styling info in
// terms of most lines or blocks with info
private Locale locale;

private String location;

/**
* Add the block to this block area.
@@ -140,5 +143,37 @@ public class Block extends BlockParent {
return (endIndent != null ? endIndent : 0);
}

/**
* Sets the language information coming from the FO that generated this area.
*/
public void setLocale(Locale locale) {
this.locale = locale;
}

/**
* Returns the language information for the FO that generated this area.
*/
public Locale getLocale() {
return locale;
}

/**
* Sets the location in the source XML of the FO that generated this area.
*
* @location the line and column location
*/
public void setLocation(String location) {
this.location = location;
}

/**
* Returns the location in the source XML of the FO that generated this area.
*
* @return the line and column location, {@code null} if that information is not available
*/
public String getLocation() {
return location;
}

}


+ 2
- 2
src/java/org/apache/fop/fo/FONode.java Voir le fichier

@@ -565,7 +565,7 @@ public abstract class FONode implements Cloneable {
/**
* Helper function to return "not supported child" exceptions. Note that the child is valid, just not
* supported yet by FOP.
*
*
* @param loc org.xml.sax.Locator object of the error (*not* parent node)
* @param nsURI namespace URI of incoming invalid node
* @param lName local name (i.e., no prefix) of incoming node
@@ -663,7 +663,7 @@ public abstract class FONode implements Cloneable {
if (loc == null) {
return "Unknown location";
} else {
return loc.getLineNumber() + "/" + loc.getColumnNumber();
return loc.getLineNumber() + ":" + loc.getColumnNumber();
}
}


+ 3
- 0
src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java Voir le fichier

@@ -31,6 +31,7 @@ import org.apache.fop.area.Area;
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.KeepProperty;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
@@ -381,6 +382,8 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
startIndent, endIndent,
this);

curBlockArea.setLocale(getBlockFO().getCommonHyphenation().getLocale());
curBlockArea.setLocation(FONode.getLocatorString(getBlockFO().getLocator()));
setCurrentArea(curBlockArea); // ??? for generic operations
}
return curBlockArea;

+ 21
- 0
src/java/org/apache/fop/render/intermediate/IFContext.java Voir le fichier

@@ -51,6 +51,8 @@ public class IFContext {

private String id = "";

private String location;

/**
* Main constructor.
* @param ua the user agent
@@ -179,4 +181,23 @@ public class IFContext {
return id;
}

/**
* Sets the location of the object enclosing the current content.
*
* @location the line and column location of the object in the source FO file
*/
public void setLocation(String location) {
this.location = location;
}

/**
* Returns the location of the object enclosing the current content.
*
* @return the line and column location of the object in the source FO file,
* {@code null} if that information is not available
*/
public String getLocation() {
return location;
}

}

+ 7
- 0
src/java/org/apache/fop/render/intermediate/IFRenderer.java Voir le fichier

@@ -965,7 +965,14 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
}
saveBlockPosIfTargetable(block);
pushdID(block);
IFContext context = documentHandler.getContext();
Locale oldLocale = context.getLanguage();
context.setLanguage(block.getLocale());
String oldLocation = context.getLocation();
context.setLocation(block.getLocation());
super.renderBlock(block);
context.setLocation(oldLocation);
context.setLanguage(oldLocale);
popID(block);
}


+ 9
- 0
src/java/org/apache/fop/render/pdf/PDFEventProducer.java Voir le fichier

@@ -74,4 +74,13 @@ public interface PDFEventProducer extends EventProducer {
* @event.severity WARN
*/
void incorrectEncryptionLength(Object source, int originalValue, int correctedValue);

/**
* The language of a piece of text is unknown.
*
* @param source the event source
* @param location location in the source FO file, if any
*/
void unknownLanguage(Object source, String location);

}

+ 1
- 0
src/java/org/apache/fop/render/pdf/PDFEventProducer.xml Voir le fichier

@@ -3,4 +3,5 @@
<message key="nonFullyResolvedLinkTargets">{count} link target{count,equals,1,,s} could not be fully resolved and now point{count,equals,1,,s} to the top of the page or {count,equals,1,is,are} dysfunctional.</message>
<message key="nonStandardStructureType">‘{type}’ is not a standard structure type defined by the PDF Reference. Falling back to ‘{fallback}’.</message>
<message key="incorrectEncryptionLength">Encryption length must be a multiple of 8 between 40 and 128. Setting encryption length to {correctedValue} instead of {originalValue}.</message>
<message key="unknownLanguage">A piece of text or an image’s alternate text is missing language information [(See position {location})|(No context info available)]</message>
</catalogue>

+ 46
- 0
src/java/org/apache/fop/render/pdf/PDFPainter.java Voir le fichier

@@ -26,6 +26,9 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

import org.w3c.dom.Document;

@@ -40,6 +43,7 @@ import org.apache.fop.pdf.PDFTextUtil;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.render.intermediate.AbstractIFPainter;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
import org.apache.fop.render.intermediate.IFUtil;
@@ -65,6 +69,41 @@ public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> {

private PDFLogicalStructureHandler logicalStructureHandler;

private final LanguageAvailabilityChecker languageAvailabilityChecker;

private static class LanguageAvailabilityChecker {

private final IFContext context;

private final Set<String> reportedLocations = new HashSet<String>();

LanguageAvailabilityChecker(IFContext context) {
this.context = context;
}

private void checkLanguageAvailability(String text) {
Locale locale = context.getLanguage();
if (locale == null && containsLettersOrDigits(text)) {
String location = context.getLocation();
if (!reportedLocations.contains(location)) {
PDFEventProducer.Provider.get(context.getUserAgent().getEventBroadcaster())
.unknownLanguage(this, location);
reportedLocations.add(location);
}
}
}

private boolean containsLettersOrDigits(String text) {
for (int i = 0; i < text.length(); i++) {
if (Character.isLetterOrDigit(text.charAt(i))) {
return true;
}
}
return false;
}

}

/**
* Default constructor.
* @param documentHandler the parent document handler
@@ -78,6 +117,9 @@ public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> {
this.borderPainter = new PDFBorderPainter(this.generator);
this.state = IFState.create();
accessEnabled = this.getUserAgent().isAccessibilityEnabled();
languageAvailabilityChecker = accessEnabled
? new LanguageAvailabilityChecker(documentHandler.getContext())
: null;
}

/** {@inheritDoc} */
@@ -130,6 +172,9 @@ public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> {

private void prepareImageMCID(PDFStructElem structElem) {
imageMCI = logicalStructureHandler.addImageContentItem(structElem);
if (structElem != null) {
languageAvailabilityChecker.checkLanguageAvailability((String) structElem.get("Alt"));
}
}

/** {@inheritDoc} */
@@ -274,6 +319,7 @@ public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> {
throws IFException {
if (accessEnabled) {
PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement();
languageAvailabilityChecker.checkLanguageAvailability(text);
MarkedContentInfo mci = logicalStructureHandler.addTextContentItem(structElem);
if (generator.getTextUtil().isInTextObject()) {
generator.separateTextElements(mci.tag, mci.mcid);

+ 4
- 0
status.xml Voir le fichier

@@ -59,6 +59,10 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
<action context="Renderers" dev="VH" type="add" fixes-bug="54037">
PDF output: Issue a warning when accessibility is enabled and language information is
missing.
</action>
<action context="Renderers" dev="VH" type="add" fixes-bug="53980">
PDF accessibility: Store language information coming from fo:block or fo:character in the
structure tree.

Chargement…
Annuler
Enregistrer