import org.apache.fop.area.RegionReference;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.Trait;
-import org.apache.fop.area.inline.Leader;
import org.apache.fop.area.inline.Image;
+import org.apache.fop.area.inline.Leader;
import org.apache.fop.area.inline.SpaceArea;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.area.inline.WordArea;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.afp.extensions.AFPElementMapping;
import org.apache.fop.render.afp.extensions.AFPPageSetup;
-import org.apache.fop.render.afp.fonts.AFPFontInfo;
import org.apache.fop.render.afp.fonts.AFPFont;
+import org.apache.fop.render.afp.fonts.AFPFontInfo;
import org.apache.fop.render.afp.fonts.CharacterSet;
import org.apache.fop.render.afp.fonts.FopCharacterSet;
import org.apache.fop.render.afp.fonts.OutlineFont;
if (!fopimage.load(FopImage.BITMAP)) {
return;
}
- convertToGrayScaleImage(io, fopimage.getBitmaps());
+ convertToGrayScaleImage(io, fopimage.getBitmaps(),
+ fopimage.getWidth(), fopimage.getHeight());
}
} else {
if (!fopimage.load(FopImage.BITMAP)) {
return;
}
- convertToGrayScaleImage(io, fopimage.getBitmaps());
+ convertToGrayScaleImage(io, fopimage.getBitmaps(),
+ fopimage.getWidth(), fopimage.getHeight());
}
} else {
if (!fopimage.load(FopImage.BITMAP)) {
io.setImageIDESize((byte)24);
io.setImageData(fopimage.getBitmaps());
} else {
- convertToGrayScaleImage(io, fopimage.getBitmaps());
+ convertToGrayScaleImage(io, fopimage.getBitmaps(),
+ fopimage.getWidth(), fopimage.getHeight());
}
}
}
} else {
//TODO Teach it how to handle grayscale BufferedImages directly
//because this is pretty inefficient
- convertToGrayScaleImage(io, buf);
+ convertToGrayScaleImage(io, buf, bi.getWidth(), bi.getHeight());
}
} catch (IOException ioe) {
log.error("Error while serializing bitmap: " + ioe.getMessage(), ioe);
return (int)Math.round(mpt / DPI_CONVERSION_FACTOR_240);
}
- private void convertToGrayScaleImage(ImageObject io, byte[] raw) {
+ /**
+ * Converts a byte array containing 24 bit RGB image data to a grayscale image.
+ * @param io the target image object
+ * @param raw the buffer containing the RGB image data
+ * @param width the width of the image in pixels
+ * @param height the height of the image in pixels
+ */
+ private void convertToGrayScaleImage(ImageObject io, byte[] raw, int width, int height) {
int pixelsPerByte = 8 / bitsPerPixel;
- byte[] bw = new byte[raw.length / (3 * pixelsPerByte)];
- int k = 0;
- for (int i = 0, j = 0; i < raw.length; i += 3, j++) {
- if (j == pixelsPerByte) {
- j = 0;
- k++;
- if (k == bw.length) {
- break;
- }
- }
- // see http://www.jguru.com/faq/view.jsp?EID=221919
- double greyVal = 0.212671d * ((int) raw[i] & 0xff)
- + 0.715160d * ((int) raw[i + 1] & 0xff)
- + 0.072169d * ((int) raw[i + 2] & 0xff);
- switch (bitsPerPixel) {
+ int bytewidth = (width / pixelsPerByte);
+ if ((width % pixelsPerByte) != 0) {
+ bytewidth++;
+ }
+ byte[] bw = new byte[height * bytewidth];
+ byte ib;
+ for (int y = 0; y < height; y++) {
+ ib = 0;
+ int i = 3 * y * width;
+ for (int x = 0; x < width; x++, i += 3) {
+
+ // see http://www.jguru.com/faq/view.jsp?EID=221919
+ double greyVal = 0.212671d * ((int) raw[i] & 0xff)
+ + 0.715160d * ((int) raw[i + 1] & 0xff)
+ + 0.072169d * ((int) raw[i + 2] & 0xff);
+
+ switch (bitsPerPixel) {
case 1:
- if (greyVal > 128) {
- bw[k] |= (byte)(1 << j);
+ if (greyVal < 128) {
+ ib |= (byte)(1 << (7 - (x % 8)));
}
break;
case 4:
greyVal /= 16;
- bw[k] |= (byte)((byte)greyVal << (j * 4));
+ ib |= (byte)((byte)greyVal << ((1 - (x % 2)) * 4));
break;
case 8:
- bw[k] = (byte)greyVal;
+ ib = (byte)greyVal;
break;
+ default:
+ throw new UnsupportedOperationException(
+ "Unsupported bits per pixel: " + bitsPerPixel);
+ }
+
+ if ((x % pixelsPerByte) == (pixelsPerByte - 1) || ((x + 1) == width)) {
+ bw[(y * bytewidth) + (x / pixelsPerByte)] = ib;
+ ib = 0;
+ }
}
}
io.setImageIDESize((byte)bitsPerPixel);
<changes>
<release version="FOP Trunk">
- <action context="code" dev="MM" type="add">
+ <action context="Code" dev="JM" type="fix">
+ AFP Renderer: Bugfix for 1 bit images where the width is not a multiple of 8.
+ </action>
+ <action context="Code" dev="MM" type="add">
Support for keep-together.within-line="always".
</action>
<action context="Code" dev="MM" type="fix">
Fixed incomplete support for Unicode Word Joiner characters (U+2060 and U+FEFF).
</action>
- <action context="code" dev="AD" type="add" fixes-bug="42785" due-to="Max Berger">
+ <action context="Code" dev="AD" type="add" fixes-bug="42785" due-to="Max Berger">
Support alignment-adjust for images.
</action>
- <action context="code" dev="AD" type="add" fixes-bug="41044" due-to="Richard Wheeldon">
+ <action context="Code" dev="AD" type="add" fixes-bug="41044" due-to="Richard Wheeldon">
Partial application of the patch in Bugzilla 41044:
* addition of a generic PropertyCache to be used by all Property
types that can be safely canonicalized
* modified EnumProperty, StringProperty, NumberProperty, EnumNumber
and FixedLength to make use of the cache infrastructure
</action>
- <action context="code" dev="AD" type="update" fixes-bug="41656">
+ <action context="Code" dev="AD" type="update" fixes-bug="41656">
Refactoring in the fo package:
-> removal of the childNodes instance member in fop.fo.FObj
-> addition of a firstChild instance member in fop.fo.FObj
-> addition of a FONodeIterator interface in FONode + corresponding implementation in FObj
-> changed implementations of FObj.addChildNode(), .removeChild() and .getChildNodes()
</action>
- <action context="code" dev="AD" type="update" fixes-bug="42089" due-to="Adrian Cumiskey">
+ <action context="Code" dev="AD" type="update" fixes-bug="42089" due-to="Adrian Cumiskey">
Code cleanup and restructuring:
Refactoring of PageSequenceLayoutManager and provide common FObj id property use
</action>