https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk ........ r670689 | adelmelle | 2008-06-23 19:01:25 +0100 (Mon, 23 Jun 2008) | 1 line Fix XMLObj.addCharacters(): incorrect after r670341 ........ r670723 | adelmelle | 2008-06-23 20:56:51 +0100 (Mon, 23 Jun 2008) | 1 line Javadoc modification + addition of clarifying comments ........ r670760 | adelmelle | 2008-06-23 22:18:45 +0100 (Mon, 23 Jun 2008) | 1 line Javadoc fixup ........ r670761 | adelmelle | 2008-06-23 22:21:09 +0100 (Mon, 23 Jun 2008) | 1 line Minor cleanup: remove unused parameter from method signature ........ r670763 | adelmelle | 2008-06-23 22:22:48 +0100 (Mon, 23 Jun 2008) | 1 line Minor cleanup: remove double storage of the FObj ........ r670765 | adelmelle | 2008-06-23 22:24:46 +0100 (Mon, 23 Jun 2008) | 1 line Minor cleanup: remove redundant cast ........ r670766 | adelmelle | 2008-06-23 22:25:30 +0100 (Mon, 23 Jun 2008) | 1 line Minor cleanup: remove redundant cast ........ r670767 | adelmelle | 2008-06-23 22:26:56 +0100 (Mon, 23 Jun 2008) | 1 line Javadoc fixup ........ r670770 | adelmelle | 2008-06-23 22:29:53 +0100 (Mon, 23 Jun 2008) | 1 line Minor cleanup: simplified conditional ........ r670773 | adelmelle | 2008-06-23 22:32:31 +0100 (Mon, 23 Jun 2008) | 1 line A nit... ........ r670777 | adelmelle | 2008-06-23 22:39:19 +0100 (Mon, 23 Jun 2008) | 1 line Fix imports... ........ r671145 | maxberger | 2008-06-24 12:59:33 +0100 (Tue, 24 Jun 2008) | 2 lines Another character handling problem, replaced end-start by length ........ r672010 | adelmelle | 2008-06-26 20:44:20 +0100 (Thu, 26 Jun 2008) | 1 line Fixed a possible NullPointerException: if the citation appears in a fo:marker, the property will only be parsed if the marker is retrieved... ........ r672026 | acumiskey | 2008-06-26 21:49:11 +0100 (Thu, 26 Jun 2008) | 5 lines Some basic cleanup. * Duplicated/redundant PSDictionary, PSPageDeviceDictionary and PSDictionaryFormatException removed and now referenced from xmlgraphics commons. * Updated xmlgraphics commons jar containing migrated PSPageDeviceDictionary class. ........ git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@672235 13f79535-47bb-0310-9956-ffa450edef68tags/fop-1_0
@@ -55,7 +55,7 @@ public interface MimeConstants { | |||
/** FrameMaker's MIF */ | |||
String MIME_MIF = "application/mif"; | |||
/** Structured Vector Graphics */ | |||
/** Scalable Vector Graphics */ | |||
String MIME_SVG = "image/svg+xml"; | |||
/** GIF images */ |
@@ -214,7 +214,7 @@ public abstract class XMLObj extends FONode implements ObjectBuiltListener { | |||
*/ | |||
protected void addCharacters(char[] data, int start, int length, | |||
PropertyList pList, Locator locator) { | |||
String str = new String(data, start, length - start); | |||
String str = new String(data, start, length); | |||
org.w3c.dom.Text text = doc.createTextNode(str); | |||
element.appendChild(text); | |||
} |
@@ -22,6 +22,7 @@ package org.apache.fop.fo.flow; | |||
import java.awt.Color; | |||
import org.xml.sax.Locator; | |||
import org.xml.sax.Attributes; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.datatypes.Length; | |||
@@ -104,13 +105,18 @@ public abstract class AbstractPageNumberCitation extends FObj { | |||
} | |||
/** {@inheritDoc} */ | |||
protected void startOfNode() throws FOPException { | |||
super.startOfNode(); | |||
if (refId.equals("")) { | |||
public void processNode(String elementName, Locator locator, Attributes attlist, PropertyList pList) throws FOPException { | |||
super.processNode(elementName, locator, attlist, pList); | |||
if (!inMarker() && (refId == null || "".equals(refId))) { | |||
missingPropertyError("ref-id"); | |||
} | |||
} | |||
/** {@inheritDoc} */ | |||
protected void startOfNode() throws FOPException { | |||
super.startOfNode(); | |||
} | |||
/** | |||
* {@inheritDoc} | |||
* <br>XSL Content Model: empty |
@@ -51,13 +51,13 @@ public class BookmarkTitle extends FObj { | |||
* | |||
* @param data the character data | |||
* @param start the start position in the data array | |||
* @param end the end position in the character array | |||
* @param length the length of the character array | |||
* @param locator location in fo source file. | |||
*/ | |||
protected void addCharacters(char[] data, int start, int end, | |||
protected void addCharacters(char[] data, int start, int length, | |||
PropertyList pList, | |||
Locator locator) { | |||
title += new String(data, start, end - start); | |||
title += new String(data, start, length); | |||
} | |||
/** |
@@ -50,8 +50,8 @@ public class SingleByteFont extends CustomFont { | |||
/** {@inheritDoc} */ | |||
public boolean isEmbeddable() { | |||
return (getEmbedFileName() == null && getEmbedResourceName() == null) ? false | |||
: true; | |||
return (!(getEmbedFileName() == null | |||
&& getEmbedResourceName() == null)); | |||
} | |||
/** {@inheritDoc} */ |
@@ -68,7 +68,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager | |||
// set layout dimensions | |||
int flowIPD = getCurrentPV().getCurrentSpan().getColumnWidth(); | |||
int flowBPD = (int) getCurrentPV().getBodyRegion().getBPD(); | |||
int flowBPD = getCurrentPV().getBodyRegion().getBPD(); | |||
// currently active LM | |||
LayoutManager curLM; |
@@ -102,18 +102,17 @@ public class PageSequenceLayoutManager extends AbstractPageSequenceLayoutManager | |||
curPage = makeNewPage(false, false); | |||
PageBreaker breaker = new PageBreaker(this); | |||
int flowBPD = (int)getCurrentPV().getBodyRegion().getRemainingBPD(); | |||
int flowBPD = getCurrentPV().getBodyRegion().getRemainingBPD(); | |||
breaker.doLayout(flowBPD); | |||
finishPage(); | |||
} | |||
/** {@inheritDoc} */ | |||
public void finishPageSequence() { | |||
if (pageSeq.hasId()) { | |||
idTracker.signalIDProcessed(pageSeq.getId()); | |||
} | |||
pageSeq.getRoot().notifyPageSequenceFinished(currentPageNum, | |||
(currentPageNum - startPageNum) + 1); | |||
areaTreeHandler.notifyPageSequenceFinished(pageSeq, | |||
@@ -150,9 +149,9 @@ public class PageSequenceLayoutManager extends AbstractPageSequenceLayoutManager | |||
return; | |||
} | |||
StaticContentLayoutManager lm = (StaticContentLayoutManager) | |||
getLayoutManagerMaker().makeStaticContentLayoutManager( | |||
this, sc, reg); | |||
StaticContentLayoutManager lm = getLayoutManagerMaker() | |||
.makeStaticContentLayoutManager( | |||
this, sc, reg); | |||
lm.doLayout(); | |||
} | |||
@@ -166,5 +165,5 @@ public class PageSequenceLayoutManager extends AbstractPageSequenceLayoutManager | |||
super.finishPage(); | |||
} | |||
} |
@@ -44,7 +44,7 @@ public class PageNumberCitationLayoutManager extends AbstractPageNumberCitationL | |||
/** {@inheritDoc} */ | |||
public InlineArea get(LayoutContext context) { | |||
curArea = getPageNumberCitationInlineArea(parentLM); | |||
curArea = getPageNumberCitationInlineArea(); | |||
return curArea; | |||
} | |||
@@ -52,7 +52,7 @@ public class PageNumberCitationLayoutManager extends AbstractPageNumberCitationL | |||
* if id can be resolved then simply return a word, otherwise | |||
* return a resolvable area | |||
*/ | |||
private InlineArea getPageNumberCitationInlineArea(LayoutManager parentLM) { | |||
private InlineArea getPageNumberCitationInlineArea() { | |||
PageViewport page = getPSLM().getFirstPVWithID(fobj.getRefId()); | |||
TextArea text = null; | |||
if (page != null) { |
@@ -20,9 +20,7 @@ | |||
package org.apache.fop.layoutmgr.inline; | |||
import org.apache.fop.area.inline.InlineArea; | |||
import org.apache.fop.area.inline.InlineParent; | |||
import org.apache.fop.area.Block; | |||
import org.apache.fop.area.LineArea; | |||
import org.apache.fop.fo.flow.Wrapper; | |||
import org.apache.fop.layoutmgr.BlockLayoutManager; | |||
import org.apache.fop.layoutmgr.BlockStackingLayoutManager; | |||
@@ -30,20 +28,19 @@ import org.apache.fop.layoutmgr.LayoutContext; | |||
import org.apache.fop.layoutmgr.PositionIterator; | |||
import org.apache.fop.layoutmgr.TraitSetter; | |||
import java.util.LinkedList; | |||
/** | |||
* This is the layout manager for the fo:wrapper formatting object. | |||
*/ | |||
public class WrapperLayoutManager extends LeafNodeLayoutManager { | |||
private Wrapper fobj; | |||
/** | |||
* Creates a new LM for fo:wrapper. | |||
* @param node the fo:wrapper | |||
*/ | |||
public WrapperLayoutManager(Wrapper node) { | |||
super(node); | |||
fobj = node; | |||
} | |||
/** {@inheritDoc} */ | |||
@@ -70,13 +67,13 @@ public class WrapperLayoutManager extends LeafNodeLayoutManager { | |||
public void addAreas(PositionIterator posIter, LayoutContext context) { | |||
if (fobj.hasId()) { | |||
addId(); | |||
InlineArea area = getEffectiveArea(); | |||
if (parentLM instanceof BlockStackingLayoutManager | |||
&& !(parentLM instanceof BlockLayoutManager)) { | |||
Block helperBlock = new Block(); | |||
TraitSetter.setProducerID(helperBlock, fobj.getId()); | |||
parentLM.addChildArea(helperBlock); | |||
} else { | |||
InlineArea area = getEffectiveArea(); | |||
parentLM.addChildArea(area); | |||
} | |||
} |
@@ -88,7 +88,6 @@ class RowGroupLayoutManager { | |||
* @param alignment alignment indicator | |||
* @param bodyType Indicates what kind of body is being processed (BODY, HEADER or FOOTER) | |||
* @param returnList List to received the generated elements | |||
* @param rowGroup row group to process | |||
*/ | |||
private void createElementsForRowGroup(LayoutContext context, int alignment, | |||
int bodyType, LinkedList returnList) { |
@@ -25,6 +25,7 @@ import java.io.OutputStream; | |||
import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; | |||
import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; | |||
import org.apache.xmlgraphics.ps.ImageEncoder; | |||
import org.apache.xmlgraphics.ps.PSDictionary; | |||
/** | |||
* ImageEncoder implementation for CCITT encoded images. |
@@ -1,312 +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.render.ps; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.StringTokenizer; | |||
/** | |||
* This class is used to encapsulate postscript dictionary objects. | |||
*/ | |||
public class PSDictionary extends java.util.HashMap { | |||
private static final long serialVersionUID = 815367222496219197L; | |||
/** | |||
* This class is used to parse dictionary strings. | |||
*/ | |||
private static class Maker { | |||
/** | |||
* Simple token holding class | |||
*/ | |||
private class Token { | |||
/** | |||
* start index in string | |||
*/ | |||
private int startIndex = -1; | |||
/** | |||
* end index in string | |||
*/ | |||
private int endIndex = -1; | |||
/** | |||
* token string value | |||
*/ | |||
private String value; | |||
} | |||
private static final String[][] BRACES = { | |||
{"<<", ">>"}, | |||
{"[", "]"}, | |||
{"{", "}"} | |||
}; | |||
private static final int OPENING = 0; | |||
private static final int CLOSING = 1; | |||
private static final int DICTIONARY = 0; | |||
private static final int ARRAY = 1; | |||
private static final int PROCEDURE = 2; | |||
/** | |||
* Returns a Token containing the start, end index and value of the next token | |||
* found in a given string | |||
* | |||
* @param str | |||
* string to search | |||
* @param fromIndex | |||
* search from index | |||
* @return Token containing the start, end index and value of the next token | |||
*/ | |||
protected Token nextToken(String str, int fromIndex) { | |||
Token t = null; | |||
for (int i = fromIndex; i < str.length(); i++) { | |||
boolean isWhitespace = Character.isWhitespace(str.charAt(i)); | |||
// start index found | |||
if (t == null && !isWhitespace) { | |||
t = new Token(); | |||
t.startIndex = i; | |||
// end index found | |||
} else if (t != null && isWhitespace) { | |||
t.endIndex = i; | |||
break; | |||
} | |||
} | |||
// start index found | |||
if (t != null) { | |||
// end index not found so take end of string | |||
if (t.endIndex == -1) { | |||
t.endIndex = str.length(); | |||
} | |||
t.value = str.substring(t.startIndex, t.endIndex); | |||
} | |||
return t; | |||
} | |||
/** | |||
* Returns the closing brace index from a given string searches from a | |||
* given index | |||
* | |||
* @param str | |||
* string to search | |||
* @param braces | |||
* string array of opening and closing brace | |||
* @param fromIndex | |||
* searches from index | |||
* @return matching brace index | |||
* @throws org.apache.fop.render.ps.PSDictionaryFormatException | |||
* thrown in the event that a parsing error occurred | |||
*/ | |||
private int indexOfMatchingBrace(String str, String[] braces, | |||
int fromIndex) throws PSDictionaryFormatException { | |||
final int len = str.length(); | |||
if (braces.length != 2) { | |||
throw new PSDictionaryFormatException("Wrong number of braces"); | |||
} | |||
for (int openCnt = 0, closeCnt = 0; fromIndex < len; fromIndex++) { | |||
if (str.startsWith(braces[OPENING], fromIndex)) { | |||
openCnt++; | |||
} else if (str.startsWith(braces[CLOSING], fromIndex)) { | |||
closeCnt++; | |||
if (openCnt > 0 && openCnt == closeCnt) { | |||
return fromIndex; // found | |||
} | |||
} | |||
} | |||
return -1; // not found | |||
} | |||
/** | |||
* Strips braces from complex object string | |||
* | |||
* @param str | |||
* String to parse | |||
* @param braces | |||
* String array containing opening and closing braces | |||
* @return String with braces stripped | |||
* @throws | |||
* org.apache.fop.render.ps.PSDictionaryFormatException object format exception | |||
*/ | |||
private String stripBraces(String str, String[] braces) throws PSDictionaryFormatException { | |||
// find first opening brace | |||
int firstIndex = str.indexOf(braces[OPENING]); | |||
if (firstIndex == -1) { | |||
throw new PSDictionaryFormatException( | |||
"Failed to find opening parameter '" + braces[OPENING] | |||
+ ""); | |||
} | |||
// find last matching brace | |||
int lastIndex = indexOfMatchingBrace(str, braces, firstIndex); | |||
if (lastIndex == -1) { | |||
throw new PSDictionaryFormatException( | |||
"Failed to find matching closing parameter '" | |||
+ braces[CLOSING] + "'"); | |||
} | |||
// strip brace and trim | |||
int braceLen = braces[OPENING].length(); | |||
str = str.substring(firstIndex + braceLen, lastIndex).trim(); | |||
return str; | |||
} | |||
/** | |||
* Parses a dictionary string and provides a dictionary object | |||
* | |||
* @param str a dictionary string | |||
* @return A postscript dictionary object | |||
* @throws | |||
* PSDictionaryFormatException thrown if a dictionary format exception occurs | |||
*/ | |||
public PSDictionary parseDictionary(String str) throws PSDictionaryFormatException { | |||
PSDictionary dictionary = new PSDictionary(); | |||
str = stripBraces(str.trim(), BRACES[DICTIONARY]); | |||
// length of dictionary string | |||
final int len = str.length(); | |||
Token keyToken; | |||
for (int currIndex = 0; (keyToken = nextToken(str, currIndex)) != null | |||
&& currIndex <= len;) { | |||
if (keyToken.value == null) { | |||
throw new PSDictionaryFormatException("Failed to parse object key"); | |||
} | |||
Token valueToken = nextToken(str, keyToken.endIndex + 1); | |||
String[] braces = null; | |||
for (int i = 0; i < BRACES.length; i++) { | |||
if (valueToken.value.startsWith(BRACES[i][OPENING])) { | |||
braces = BRACES[i]; | |||
break; | |||
} | |||
} | |||
Object obj = null; | |||
if (braces != null) { | |||
// find closing brace | |||
valueToken.endIndex = indexOfMatchingBrace(str, braces, | |||
valueToken.startIndex) | |||
+ braces[OPENING].length(); | |||
if (valueToken.endIndex < 0) { | |||
throw new PSDictionaryFormatException("Closing value brace '" | |||
+ braces[CLOSING] + "' not found for key '" | |||
+ keyToken.value + "'"); | |||
} | |||
valueToken.value = str.substring(valueToken.startIndex, valueToken.endIndex); | |||
} | |||
if (braces == null || braces == BRACES[PROCEDURE]) { | |||
obj = valueToken.value; | |||
} else if (BRACES[ARRAY] == braces) { | |||
List objList = new java.util.ArrayList(); | |||
String objString = stripBraces(valueToken.value, braces); | |||
StringTokenizer tokenizer = new StringTokenizer(objString, ","); | |||
while (tokenizer.hasMoreTokens()) { | |||
objList.add(tokenizer.nextToken()); | |||
} | |||
obj = objList; | |||
} else if (BRACES[DICTIONARY] == braces) { | |||
obj = parseDictionary(valueToken.value); | |||
} | |||
dictionary.put(keyToken.value, obj); | |||
currIndex = valueToken.endIndex + 1; | |||
} | |||
return dictionary; | |||
} | |||
} | |||
/** | |||
* Parses a given a dictionary string and returns an object | |||
* | |||
* @param str dictionary string | |||
* @return dictionary object | |||
* @throws PSDictionaryFormatException object format exception | |||
*/ | |||
public static PSDictionary valueOf(String str) throws PSDictionaryFormatException { | |||
return (new Maker()).parseDictionary(str); | |||
} | |||
/** | |||
* @param obj object to test equality against | |||
* @return whether a given object is equal to this dictionary object | |||
* @see java.lang.Object#equals(Object) | |||
*/ | |||
public boolean equals(Object obj) { | |||
if (!(obj instanceof PSPageDeviceDictionary)) { | |||
return false; | |||
} | |||
PSDictionary dictionaryObj = (PSDictionary) obj; | |||
if (dictionaryObj.size() != size()) { | |||
return false; | |||
} | |||
for (Iterator it = keySet().iterator(); it.hasNext();) { | |||
String key = (String) it.next(); | |||
if (!dictionaryObj.containsKey(key)) { | |||
return false; | |||
} | |||
if (!dictionaryObj.get(key).equals(get(key))) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
/** | |||
* @return a hash code value for this object. | |||
* @see java.lang.Object#hashCode() | |||
*/ | |||
public int hashCode() { | |||
int hashCode = 7; | |||
for (Iterator it = values().iterator(); it.hasNext();) { | |||
Object value = it.next(); | |||
hashCode += value.hashCode(); | |||
} | |||
return hashCode; | |||
} | |||
/** | |||
* @return a string representation of this dictionary | |||
* @see java.lang.String#toString() | |||
*/ | |||
public String toString() { | |||
if (isEmpty()) { | |||
return ""; | |||
} | |||
StringBuffer sb = new StringBuffer("<<\n"); | |||
for (Iterator it = super.keySet().iterator(); it.hasNext();) { | |||
String key = (String) it.next(); | |||
sb.append(" " + key + " "); | |||
Object obj = super.get(key); | |||
if (obj instanceof java.util.ArrayList) { | |||
List array = (List)obj; | |||
String str = "["; | |||
for (int i = 0; i < array.size(); i++) { | |||
Object element = array.get(i); | |||
str += element + " "; | |||
} | |||
str = str.trim(); | |||
str += "]"; | |||
sb.append(str + "\n"); | |||
} else { | |||
sb.append(obj.toString() + "\n"); | |||
} | |||
} | |||
sb.append(">>"); | |||
return sb.toString(); | |||
} | |||
} |
@@ -1,37 +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.render.ps; | |||
/** | |||
* Thrown to indicate that a formatting error has occured when | |||
* trying to parse a postscript dictionary object | |||
*/ | |||
public class PSDictionaryFormatException extends Exception { | |||
private static final long serialVersionUID = 6492321557297860931L; | |||
/** | |||
* Default constructor | |||
* @param string error message | |||
*/ | |||
public PSDictionaryFormatException(String string) { | |||
super(string); | |||
} | |||
} |
@@ -1,110 +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.render.ps; | |||
/** | |||
* Postscript page device dictionary object | |||
* | |||
* This object is used by the postscript renderer to hold postscript page device | |||
* values. It can also be used to minimize the number of setpagedevice calls when | |||
* DSC compliance is false. | |||
*/ | |||
public class PSPageDeviceDictionary extends PSDictionary { | |||
private static final long serialVersionUID = 845943256485806509L; | |||
/** | |||
* Whether or not the contents of the dictionary are flushed on retrieval | |||
*/ | |||
private boolean flushOnRetrieval = false; | |||
/** | |||
* Dictionary content that has not been output/written yet | |||
*/ | |||
private PSDictionary unRetrievedContentDictionary; | |||
/** | |||
* @param key key with which the specified value is to be associated. | |||
* @param value value to be associated with the specified key. | |||
* @return the previous value associated with the key or null | |||
* @see java.util.Map#put(Object, Object) | |||
*/ | |||
public Object put(Object key, Object value) { | |||
Object previousValue = super.put(key, value); | |||
if (flushOnRetrieval) { | |||
if (previousValue == null || !previousValue.equals(value)) { | |||
unRetrievedContentDictionary.put(key, value); | |||
} | |||
} | |||
return previousValue; | |||
} | |||
/** | |||
* @see java.util.Map#clear() | |||
*/ | |||
public void clear() { | |||
super.clear(); | |||
if (unRetrievedContentDictionary != null) { | |||
unRetrievedContentDictionary.clear(); | |||
} | |||
} | |||
/** | |||
* Returns <tt>true</tt> if this map contains no key-value mappings. | |||
* | |||
* @return <tt>true</tt> if this map contains no key-value mappings. | |||
*/ | |||
public boolean isEmpty() { | |||
if (flushOnRetrieval) { | |||
return unRetrievedContentDictionary.isEmpty(); | |||
} | |||
return super.isEmpty(); | |||
} | |||
/** | |||
* The contents of the dictionary are flushed when written | |||
* @param flushOnRetrieval boolean value | |||
*/ | |||
public void setFlushOnRetrieval(boolean flushOnRetrieval) { | |||
this.flushOnRetrieval = flushOnRetrieval; | |||
if (flushOnRetrieval) { | |||
unRetrievedContentDictionary = new PSDictionary(); | |||
} | |||
} | |||
/** | |||
* Returns a dictionary string with containing all unwritten content note: | |||
* unnecessary writes are important as there is a device specific | |||
* initgraphics call by the underlying postscript interpreter on every | |||
* setpagedevice call which can result in blank pages etc. | |||
* | |||
* @return unwritten content dictionary string | |||
*/ | |||
public String getContent() { | |||
String content; | |||
if (flushOnRetrieval) { | |||
content = unRetrievedContentDictionary.toString(); | |||
unRetrievedContentDictionary.clear(); | |||
} else { | |||
content = super.toString(); | |||
} | |||
return content; | |||
} | |||
} |
@@ -57,6 +57,9 @@ import org.apache.xmlgraphics.image.loader.pipeline.ImageProviderPipeline; | |||
import org.apache.xmlgraphics.image.loader.util.ImageUtil; | |||
import org.apache.xmlgraphics.ps.DSCConstants; | |||
import org.apache.xmlgraphics.ps.ImageEncoder; | |||
import org.apache.xmlgraphics.ps.PSDictionary; | |||
import org.apache.xmlgraphics.ps.PSPageDeviceDictionary; | |||
import org.apache.xmlgraphics.ps.PSDictionaryFormatException; | |||
import org.apache.xmlgraphics.ps.PSGenerator; | |||
import org.apache.xmlgraphics.ps.PSImageUtils; | |||
import org.apache.xmlgraphics.ps.PSProcSets; |
@@ -78,7 +78,7 @@ public abstract class PSExtensionAttachment implements ExtensionAttachment, XMLi | |||
* | |||
* @param handler ContentHandler instance to send the SAX events to | |||
* @throws SAXException if there's a problem generating the SAX events | |||
* @see org.apache.fop.util.XMLizable#toSAX(org.xml.sax.ContentHandler) | |||
* @see org.apache.xmlgraphics.util.XMLizable#toSAX(org.xml.sax.ContentHandler) | |||
*/ | |||
public void toSAX(ContentHandler handler) throws SAXException { | |||
AttributesImpl atts = new AttributesImpl(); |
@@ -61,52 +61,90 @@ public class LineBreakStatus { | |||
} | |||
/** | |||
* Check whether a line break may happen. | |||
* The function returns the line breaking status of the point before the given character. | |||
* The algorithm is the table driven algorithm described in the Unicode | |||
* <a href="http://unicode.org/reports/tr14/#PairBasedImplementation">technical report #14</a>. | |||
* The pair table is taken from @see LineBreakUtils | |||
* Check whether a line break may happen according to the rules described in | |||
* the <a href="http://unicode.org/reports/tr14/#Algorithm">Unicode Line Breaking Algorithm</a>. | |||
* The function returns the line breaking status of the point <em>before</em> the given character. | |||
* The algorithm is the table-driven algorithm, as described in | |||
* <a href="http://unicode.org/reports/tr14/#PairBasedImplementation"> | |||
* Unicode Technical Report #14</a>. | |||
* The pair table is taken from {@link LineBreakUtils}. | |||
* | |||
* TODO: Better handling for AI, SA, CB and other line break classes. | |||
* TODO: Better handling for AI, SA, SG and XX line break classes. | |||
* | |||
* @param c The character. | |||
* @param c the character to check | |||
* @return the break action to be taken | |||
* one of: {@link #DIRECT_BREAK}, | |||
* {@link #INDIRECT_BREAK}, | |||
* {@link #COMBINING_INDIRECT_BREAK}, | |||
* {@link #COMBINING_PROHIBITED_BREAK}, | |||
* {@link #PROHIBITED_BREAK}, | |||
* {@link #EXPLICIT_BREAK} | |||
*/ | |||
public byte nextChar(char c) { | |||
byte currentClass = LineBreakUtils.getLineBreakProperty(c); | |||
if (currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_AI | |||
|| leftClass == LineBreakUtils.LINE_BREAK_PROPERTY_XX) { | |||
//current "Ambiguous" or previous "Unknown": | |||
// assume current "Alphabetic" | |||
currentClass = LineBreakUtils.LINE_BREAK_PROPERTY_AL; | |||
/* Initial conversions */ | |||
switch (currentClass) { | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_AI: | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_SG: | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_XX: | |||
// LB 1: Resolve AI, ... SG and XX into other line breaking classes | |||
// depending on criteria outside the scope of this algorithm. | |||
// In the absence of such criteria, it is recommended that | |||
// classes AI, ... SG and XX be resolved to AL | |||
currentClass = LineBreakUtils.LINE_BREAK_PROPERTY_AL; | |||
break; | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_SA: | |||
// LB 1: Resolve ... SA ... into other line breaking classes | |||
// depending on criteria outside the scope of this algorithm. | |||
// In the absence of such criteria, it is recommended that | |||
// ... SA be resolved to AL, except that characters of | |||
// class SA that have General_Category Mn or Mc be resolved to CM | |||
switch (Character.getType(c)) { | |||
case Character.COMBINING_SPACING_MARK: //General_Category "Mc" | |||
case Character.NON_SPACING_MARK: //General_Category "Mn" | |||
currentClass = LineBreakUtils.LINE_BREAK_PROPERTY_CM; | |||
break; | |||
default: | |||
currentClass = LineBreakUtils.LINE_BREAK_PROPERTY_AL; | |||
} | |||
default: | |||
//nop | |||
} | |||
/** Check 1: initial character after a reset/mandatory break? */ | |||
/* Check 1: First character or initial character after a reset/mandatory break? */ | |||
switch (leftClass) { | |||
case -1: | |||
//first character after a reset() | |||
//first character or initial character after a reset() | |||
leftClass = currentClass; | |||
if (leftClass == LineBreakUtils.LINE_BREAK_PROPERTY_CM) { | |||
leftClass = LineBreakUtils.LINE_BREAK_PROPERTY_ID; | |||
// LB 10: Treat any remaining combining marks as AL | |||
leftClass = LineBreakUtils.LINE_BREAK_PROPERTY_AL; | |||
} | |||
// LB 2a | |||
// LB 2: Never break at the start of text | |||
return PROHIBITED_BREAK; | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_BK: | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_LF: | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_NL: | |||
//first character after mandatory break | |||
// LB 4: Always break after hard line breaks | |||
// LB 5: Treat ... LF and NL has hard line breaks | |||
reset(); | |||
leftClass = currentClass; | |||
return EXPLICIT_BREAK; | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_CR: | |||
//first character after a carriage return: | |||
// explicit break if it is not a linefeed | |||
// LB 5: Treat CR followed by LF, as well as CR ... as hard line breaks | |||
// If current is LF, then fall through to Check 2 (see below), | |||
// and the hard break will be signaled for the character after LF (see above) | |||
if (currentClass != LineBreakUtils.LINE_BREAK_PROPERTY_LF) { | |||
reset(); | |||
leftClass = currentClass; | |||
return EXPLICIT_BREAK; | |||
} | |||
@@ -114,16 +152,19 @@ public class LineBreakStatus { | |||
//nop | |||
} | |||
/** Check 2: current is a mandatory break or space? */ | |||
/* Check 2: current is a mandatory break or space? */ | |||
switch (currentClass) { | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_BK: | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_LF: | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_NL: | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_CR: | |||
// LB 6: Do not break before a hard break | |||
leftClass = currentClass; | |||
return PROHIBITED_BREAK; | |||
case LineBreakUtils.LINE_BREAK_PROPERTY_SP: | |||
// LB 7: Do not break before spaces ... | |||
// Zero-width spaces are in the pair-table (see below) | |||
hadSpace = true; | |||
return PROHIBITED_BREAK; | |||
@@ -131,7 +172,7 @@ public class LineBreakStatus { | |||
//nop | |||
} | |||
/** Normal treatment, if the first two checks did not return */ | |||
/* Normal treatment, if the first two checks did not return */ | |||
boolean savedHadSpace = hadSpace; | |||
hadSpace = false; | |||
byte breakAction = LineBreakUtils.getLineBreakPairProperty(leftClass, currentClass); |