Skip to content

Commit

Permalink
PDFBOX-5852: replace Map with a two-dimensional array
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.apache.org/repos/asf/pdfbox/trunk@1920718 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
lehmi committed Sep 16, 2024
1 parent 6958ade commit 1c31c9d
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@
*/
package org.apache.pdfbox.pdmodel.graphics.shading;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.pdfbox.util.Matrix;

Expand Down Expand Up @@ -62,11 +59,11 @@ final void setTriangleList(List<ShadedTriangle> triangleList)
}

@Override
protected Map<Point, Integer> calcPixelTable(Rectangle deviceBounds) throws IOException
protected Integer[][] calcPixelTableArray(Rectangle deviceBounds) throws IOException
{
Map<Point, Integer> map = new HashMap<>();
super.calcPixelTable(triangleList, map, deviceBounds);
return map;
Integer[][] array = new Integer[deviceBounds.width + 1][deviceBounds.height + 1];
calcPixelTable(triangleList, array, deviceBounds);
return array;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@
*/
package org.apache.pdfbox.pdmodel.graphics.shading;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.pdfbox.util.Matrix;

Expand Down Expand Up @@ -60,14 +57,14 @@ protected PatchMeshesShadingContext(PDMeshBasedShadingType shading, ColorModel c
}

@Override
protected Map<Point, Integer> calcPixelTable(Rectangle deviceBounds) throws IOException
protected Integer[][] calcPixelTableArray(Rectangle deviceBounds) throws IOException
{
Map<Point, Integer> map = new HashMap<>();
Integer[][] array = new Integer[deviceBounds.width][deviceBounds.height];
for (Patch it : patchList)
{
super.calcPixelTable(it.listOfTriangles, map, deviceBounds);
calcPixelTable(it.listOfTriangles, array, deviceBounds);
}
return map;
return array;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.awt.image.WritableRaster;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.pdfbox.util.Matrix;

Expand All @@ -36,8 +35,12 @@
*/
abstract class TriangleBasedShadingContext extends ShadingContext
{
// map of pixels within triangles to their RGB color
private Map<Point, Integer> pixelTable;
// array of pixels within triangles to their RGB color
private Integer[][] pixelTableArray;

// offset to be used for the array index
private int xOffset = 0;
private int yOffset = 0;

/**
* Constructor.
Expand All @@ -59,20 +62,22 @@ abstract class TriangleBasedShadingContext extends ShadingContext
*/
protected final void createPixelTable(Rectangle deviceBounds) throws IOException
{
pixelTable = calcPixelTable(deviceBounds);
xOffset = -deviceBounds.x;
yOffset = -deviceBounds.y;
pixelTableArray = calcPixelTableArray(deviceBounds);
}

/**
* Calculate every point and its color and store them in a Hash table.
* Calculate every point and its color and store them in a two-dimensional array.
*
* @return a Hash table which contains all the points' positions and colors of one image
* @return an array which contains all the points' positions and colors of one image
*/
abstract Map<Point, Integer> calcPixelTable(Rectangle deviceBounds) throws IOException;
abstract Integer[][] calcPixelTableArray(Rectangle deviceBounds) throws IOException;

/**
* Get the points from the triangles, calculate their color and add point-color mappings.
*/
protected void calcPixelTable(List<ShadedTriangle> triangleList, Map<Point, Integer> map,
protected void calcPixelTable(List<ShadedTriangle> triangleList, Integer[][] array,
Rectangle deviceBounds) throws IOException
{
for (ShadedTriangle tri : triangleList)
Expand All @@ -83,7 +88,7 @@ protected void calcPixelTable(List<ShadedTriangle> triangleList, Map<Point, Inte
Line line = tri.getLine();
for (Point p : line.linePoints)
{
map.put(p, evalFunctionAndConvertToRGB(line.calcColor(p)));
addValueToArray(p, evalFunctionAndConvertToRGB(line.calcColor(p)), array);
}
}
else
Expand All @@ -98,41 +103,65 @@ protected void calcPixelTable(List<ShadedTriangle> triangleList, Map<Point, Inte
{
for (int y = boundary[2]; y <= boundary[3]; y++)
{
Point p = new IntPoint(x, y);
Point p = new Point(x, y);
if (tri.contains(p))
{
map.put(p, evalFunctionAndConvertToRGB(tri.calcColor(p)));
addValueToArray(p, evalFunctionAndConvertToRGB(tri.calcColor(p)),
array);
}
}
}

// "fatten" triangle by drawing the borders with Bresenham's line algorithm
// Inspiration: Raph Levien in http://bugs.ghostscript.com/show_bug.cgi?id=219588
Point p0 = new IntPoint((int) Math.round(tri.corner[0].getX()),
Point p0 = new Point((int) Math.round(tri.corner[0].getX()),
(int) Math.round(tri.corner[0].getY()));
Point p1 = new IntPoint((int) Math.round(tri.corner[1].getX()),
Point p1 = new Point((int) Math.round(tri.corner[1].getX()),
(int) Math.round(tri.corner[1].getY()));
Point p2 = new IntPoint((int) Math.round(tri.corner[2].getX()),
Point p2 = new Point((int) Math.round(tri.corner[2].getX()),
(int) Math.round(tri.corner[2].getY()));
Line l1 = new Line(p0, p1, tri.color[0], tri.color[1]);
Line l2 = new Line(p1, p2, tri.color[1], tri.color[2]);
Line l3 = new Line(p2, p0, tri.color[2], tri.color[0]);
for (Point p : l1.linePoints)
{
map.put(p, evalFunctionAndConvertToRGB(l1.calcColor(p)));
addValueToArray(p, evalFunctionAndConvertToRGB(l1.calcColor(p)), array);
}
for (Point p : l2.linePoints)
{
map.put(p, evalFunctionAndConvertToRGB(l2.calcColor(p)));
addValueToArray(p, evalFunctionAndConvertToRGB(l2.calcColor(p)), array);
}
for (Point p : l3.linePoints)
{
map.put(p, evalFunctionAndConvertToRGB(l3.calcColor(p)));
addValueToArray(p, evalFunctionAndConvertToRGB(l3.calcColor(p)), array);
}
}
}
}

private void addValueToArray(Point p, int value, Integer[][] array)
{
int xIndex = p.x + xOffset;
int yIndex = p.y + yOffset;
if (xIndex < 0 || yIndex < 0 || xIndex >= array.length || yIndex >= array[0].length)
{
return;
}
array[xIndex][yIndex] = value;
}

private Integer getValueFromArray(int x, int y)
{
int xIndex = x + xOffset;
int yIndex = y + yOffset;
if (xIndex < 0 || yIndex < 0 || xIndex >= pixelTableArray.length
|| yIndex >= pixelTableArray[0].length)
{
return null;
}
return pixelTableArray[xIndex][yIndex];
}

/**
* Convert color to RGB color value, using function if required, then convert from the shading
* color space to an RGB value, which is encoded into an integer.
Expand Down Expand Up @@ -162,9 +191,8 @@ public final Raster getRaster(int x, int y, int w, int h)
{
for (int col = 0; col < w; col++)
{
Point p = new IntPoint(x + col, y + row);
int value;
Integer v = pixelTable.get(p);
Integer v = getValueFromArray(x + col, y + row);
if (v != null)
{
value = v;
Expand Down

0 comments on commit 1c31c9d

Please sign in to comment.