public void setAppearanceValue(String apValue) throws IOException {
// MulitLine check and set
if ( parent.isMultiline() && apValue.indexOf('\n') != -1 )
{
apValue = convertToMultiLine( apValue );
}
value = apValue;
Iterator widgetIter = widgets.iterator();
while( widgetIter.hasNext() )
{
Object next = widgetIter.next();
PDField field = null;
PDAnnotationWidget widget = null;
if( next instanceof PDField )
{
field = (PDField)next;
widget = field.getWidget();
}
else
{
widget = (PDAnnotationWidget)next;
}
PDFormFieldAdditionalActions actions = null;
if( field != null )
{
actions = field.getActions();
}
if( actions != null &&
actions.getF() != null &&
widget.getDictionary().getDictionaryObject( "AP" ) ==null)
{
//do nothing because the field will be formatted by acrobat
//when it is opened. See FreedomExpressions.pdf for an example of this.
}
else
{
PDAppearanceDictionary appearance = widget.getAppearance();
if( appearance == null )
{
appearance = new PDAppearanceDictionary();
widget.setAppearance( appearance );
}
Map normalAppearance = appearance.getNormalAppearance();
PDAppearanceStream appearanceStream = (PDAppearanceStream)normalAppearance.get( "default" );
if( appearanceStream == null )
{
COSStream cosStream = new COSStream( acroForm.getDocument().getDocument().getScratchFile() );
appearanceStream = new PDAppearanceStream( cosStream );
appearanceStream.setBoundingBox( widget.getRectangle().createRetranslatedRectangle() );
appearance.setNormalAppearance( appearanceStream );
}
List tokens = getStreamTokens( appearanceStream );
List daTokens = getStreamTokens( getDefaultAppearance() );
PDFont pdFont = getFontAndUpdateResources( tokens, appearanceStream );
if (!containsMarkedContent( tokens ))
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
//BJL 9/25/2004 Must prepend existing stream
//because it might have operators to draw things like
//rectangles and such
ContentStreamWriter writer = new ContentStreamWriter( output );
writer.writeTokens( tokens );
output.write( " /Tx BMC\n".getBytes() );
insertGeneratedAppearance( widget, output, pdFont, tokens, appearanceStream );
output.write( " EMC".getBytes() );
writeToStream( output.toByteArray(), appearanceStream );
}
else
{
if( tokens != null )
{
if( daTokens != null )
{
int bmcIndex = tokens.indexOf( PDFOperator.getOperator( "BMC" ));
int emcIndex = tokens.indexOf( PDFOperator.getOperator( "EMC" ));
if( bmcIndex != -1 && emcIndex != -1 &&
emcIndex == bmcIndex+1 )
{
//if the EMC immediately follows the BMC index then should
//insert the daTokens inbetween the two markers.
tokens.addAll( emcIndex, daTokens );
}
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
ContentStreamWriter writer = new ContentStreamWriter( output );
float fontSize = calculateFontSize( pdFont, appearanceStream.getBoundingBox(), tokens, null );
boolean foundString = false;
for( int i=0; i< tokens.size(); i++ )
{
if( tokens.get( i ) instanceof COSString )
{
foundString = true;
COSString drawnString =((COSString)tokens.get(i));
drawnString.reset();
drawnString.append( apValue.getBytes() );
}
}
int setFontIndex = tokens.indexOf( PDFOperator.getOperator( "Tf" ));
tokens.set( setFontIndex-1, new COSFloat( fontSize ) );
if( foundString )
{
writer.writeTokens( tokens );
}
else
{
int bmcIndex = tokens.indexOf( PDFOperator.getOperator( "BMC" ) );
int emcIndex = tokens.indexOf( PDFOperator.getOperator( "EMC" ) );
if( bmcIndex != -1 )
{
writer.writeTokens( tokens, 0, bmcIndex+1 );
}
else
{
writer.writeTokens( tokens );
}
output.write( "\n".getBytes() );
insertGeneratedAppearance( widget, output,
pdFont, tokens, appearanceStream );
if( emcIndex != -1 )
{
writer.writeTokens( tokens, emcIndex, tokens.size() );
}
}
writeToStream( output.toByteArray(), appearanceStream );
}
else
{
//hmm?
}
}
}
}
}
This is the public method for setting the appearance stream. |