Skip to content

Commit 7b4fadc

Browse files
committed
Rotation code tweaks
1 parent b0adcea commit 7b4fadc

File tree

9 files changed

+137
-120
lines changed

9 files changed

+137
-120
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ and data.
159159
- Codablock F: allow user to customize row height
160160
- Codablock F: allow user to customize module width
161161
- Codablock F: improve check digit calculation
162+
- Add optional rotation parameter to all renderers
162163

163164
#### Okapi Barcode 0.4.8
164165
- MaxiCode: improve handling of partial and malformed postal codes (modes 2 and 3)

src/main/java/uk/org/okapibarcode/output/Java2DRenderer.java

+6-12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static uk.org.okapibarcode.graphics.TextAlignment.CENTER;
2020
import static uk.org.okapibarcode.graphics.TextAlignment.JUSTIFY;
21+
import static uk.org.okapibarcode.util.Integers.normalizeRotation;
2122

2223
import java.awt.Font;
2324
import java.awt.FontMetrics;
@@ -58,7 +59,7 @@ public class Java2DRenderer implements SymbolRenderer {
5859
/** The ink (foreground) color. */
5960
private final Color ink;
6061

61-
/** The clockwise rotation of the symbol in degrees (0, 90, 180, or 270). */
62+
/** The clockwise rotation of the symbol in degrees. */
6263
private final int rotation;
6364

6465
/**
@@ -82,14 +83,14 @@ public Java2DRenderer(Graphics2D g2d, double magnification, Color paper, Color i
8283
* @param magnification the magnification factor to apply
8384
* @param paper the paper (background) color (may be {@code null})
8485
* @param ink the ink (foreground) color
85-
* @param rotation the clockwise rotation of the symbol in degrees (0, 90, 180, or 270)
86+
* @param rotation the clockwise rotation of the symbol in degrees (must be a multiple of 90)
8687
*/
8788
public Java2DRenderer(Graphics2D g2d, double magnification, Color paper, Color ink, int rotation) {
8889
this.g2d = g2d;
8990
this.magnification = magnification;
9091
this.paper = paper;
9192
this.ink = ink;
92-
this.rotation = SymbolRenderer.normalizeRotation(rotation);
93+
this.rotation = normalizeRotation(rotation);
9394
}
9495

9596
/** {@inheritDoc} */
@@ -100,29 +101,22 @@ public void render(Symbol symbol) {
100101
int height = (int) (symbol.getHeight() * magnification);
101102
int marginX = (int) (symbol.getQuietZoneHorizontal() * magnification);
102103
int marginY = (int) (symbol.getQuietZoneVertical() * magnification);
103-
int rotateHeight = height;
104-
int rotateWidth = width;
105104

106-
// render rotation clockwise
107105
AffineTransform oldTransform = null;
108106
if (rotation != 0) {
109107
oldTransform = g2d.getTransform();
110108
switch (rotation) {
111109
case 90:
112-
rotateHeight = width;
113-
rotateWidth = height;
114110
g2d.rotate(Math.PI / 2d);
115-
g2d.translate(0, -rotateWidth);
111+
g2d.translate(0, -height);
116112
break;
117113
case 180:
118114
g2d.rotate(Math.PI);
119115
g2d.translate(-width, -height);
120116
break;
121117
case 270:
122-
rotateHeight = width;
123-
rotateWidth = height;
124118
g2d.rotate(Math.PI * 1.5d);
125-
g2d.translate(-rotateHeight, 0);
119+
g2d.translate(-width, 0);
126120
break;
127121
}
128122
}

src/main/java/uk/org/okapibarcode/output/PostScriptRenderer.java

+15-16
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static uk.org.okapibarcode.graphics.TextAlignment.CENTER;
2020
import static uk.org.okapibarcode.graphics.TextAlignment.JUSTIFY;
2121
import static uk.org.okapibarcode.util.Doubles.roughlyEqual;
22+
import static uk.org.okapibarcode.util.Integers.normalizeRotation;
2223

2324
import java.io.IOException;
2425
import java.io.OutputStream;
@@ -74,14 +75,14 @@ public PostScriptRenderer(OutputStream out, double magnification, Color paper, C
7475
* @param magnification the magnification factor to apply
7576
* @param paper the paper (background) color
7677
* @param ink the ink (foreground) color
77-
* @param rotation the clockwise rotation of the symbol in degrees (0, 90, 180, or 270)
78+
* @param rotation the clockwise rotation of the symbol in degrees (must be a multiple of 90)
7879
*/
7980
public PostScriptRenderer(OutputStream out, double magnification, Color paper, Color ink, int rotation) {
8081
this.out = out;
8182
this.magnification = magnification;
8283
this.paper = paper;
8384
this.ink = ink;
84-
this.rotation = SymbolRenderer.normalizeRotation(rotation);
85+
this.rotation = normalizeRotation(rotation);
8586
}
8687

8788
/** {@inheritDoc} */
@@ -96,19 +97,17 @@ public void render(Symbol symbol) throws IOException {
9697
int marginX = (int) (symbol.getQuietZoneHorizontal() * magnification);
9798
int marginY = (int) (symbol.getQuietZoneVertical() * magnification);
9899

99-
// render rotation clockwise
100-
int rotateHeight = height;
101-
int rotateWidth = width;
102-
String transform;
103-
switch (rotation) {
104-
case 90:
105-
case 270:
106-
rotateHeight = width;
107-
rotateWidth = height;
108-
break;
109-
default:
110-
break;
111-
}
100+
int rotatedHeight = height;
101+
int rotatedWidth = width;
102+
switch (rotation) {
103+
case 90:
104+
case 270:
105+
rotatedHeight = width;
106+
rotatedWidth = height;
107+
break;
108+
default:
109+
break;
110+
}
112111

113112
String title;
114113
if (content.isEmpty()) {
@@ -124,7 +123,7 @@ public void render(Symbol symbol) throws IOException {
124123
writer.append("%%Creator: OkapiBarcode\n");
125124
writer.append("%%Title: ").append(title).append('\n');
126125
writer.append("%%Pages: 0\n");
127-
writer.append("%%BoundingBox: 0 0 ").appendInt(rotateWidth).append(" ").appendInt(rotateHeight).append("\n");
126+
writer.append("%%BoundingBox: 0 0 ").appendInt(rotatedWidth).append(" ").appendInt(rotatedHeight).append("\n");
128127
writer.append("%%EndComments\n");
129128

130129
// Definitions

src/main/java/uk/org/okapibarcode/output/SvgRenderer.java

+16-17
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static uk.org.okapibarcode.graphics.TextAlignment.CENTER;
2020
import static uk.org.okapibarcode.graphics.TextAlignment.JUSTIFY;
21+
import static uk.org.okapibarcode.util.Integers.normalizeRotation;
2122

2223
import java.io.IOException;
2324
import java.io.OutputStream;
@@ -67,7 +68,7 @@ public class SvgRenderer implements SymbolRenderer {
6768

6869
/** Whether or not to include the XML prolog in the output. */
6970
private final boolean xmlProlog;
70-
71+
7172
/** The clockwise rotation of the symbol in degrees. */
7273
private final int rotation;
7374

@@ -94,15 +95,15 @@ public SvgRenderer(OutputStream out, double magnification, Color paper, Color in
9495
* @param ink the ink (foreground) color
9596
* @param xmlProlog whether or not to include the XML prolog in the output (usually {@code true} for
9697
* standalone SVG documents, {@code false} for SVG content embedded directly in HTML documents)
97-
* @param rotation the clockwise rotation of the symbol in degrees (0, 90, 180, or 270)
98+
* @param rotation the clockwise rotation of the symbol in degrees (must be a multiple of 90)
9899
*/
99100
public SvgRenderer(OutputStream out, double magnification, Color paper, Color ink, boolean xmlProlog, int rotation) {
100101
this.out = out;
101102
this.magnification = magnification;
102103
this.paper = paper;
103104
this.ink = ink;
104105
this.xmlProlog = xmlProlog;
105-
this.rotation = SymbolRenderer.normalizeRotation(rotation);
106+
this.rotation = normalizeRotation(rotation);
106107
}
107108

108109
/** {@inheritDoc} */
@@ -139,37 +140,35 @@ public void render(Symbol symbol) throws IOException {
139140
writer.append(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
140141
}
141142

142-
// render rotation clockwise
143-
int rotateHeight = height;
144-
int rotateWidth = width;
143+
// Rotation
144+
int rotatedHeight = height;
145+
int rotatedWidth = width;
145146
String transform;
146147
switch (rotation) {
147148
case 90:
148-
rotateHeight = width;
149-
rotateWidth = height;
150-
transform = " transform=\"rotate(" + rotation + ") translate(0,-" + rotateWidth + ")\"";
149+
rotatedHeight = width;
150+
rotatedWidth = height;
151+
transform = " transform=\"rotate(" + rotation + ") translate(0,-" + rotatedWidth + ")\"";
151152
break;
152153
case 180:
153-
transform = " transform=\"rotate(" + rotation + "," + (width/2) + "," + (height/2) + ")\"";
154+
transform = " transform=\"rotate(" + rotation + "," + (width / 2) + "," + (height / 2) + ")\"";
154155
break;
155156
case 270:
156-
rotateHeight = width;
157-
rotateWidth = height;
158-
transform = " transform=\"rotate(" + rotation + ") translate(-" + rotateHeight + ",0)\"";
157+
rotatedHeight = width;
158+
rotatedWidth = height;
159+
transform = " transform=\"rotate(" + rotation + ") translate(-" + rotatedHeight + ",0)\"";
159160
break;
160161
default:
161162
transform = "";
162163
break;
163164
}
164165

165166
// Header
166-
writer.append("<svg width=\"").appendInt(rotateWidth)
167-
.append("\" height=\"").appendInt(rotateHeight)
167+
writer.append("<svg width=\"").appendInt(rotatedWidth)
168+
.append("\" height=\"").appendInt(rotatedHeight)
168169
.append("\" version=\"1.1")
169170
.append("\" xmlns=\"http://www.w3.org/2000/svg\">\n");
170171
writer.append(" <desc>").append(clean(title)).append("</desc>\n");
171-
172-
173172
writer.append(" <g id=\"barcode\" fill=\"#").append(fgColour).append("\"").append(transform).append(">\n");
174173
writer.append(" <rect x=\"0\" y=\"0\" width=\"").appendInt(width)
175174
.append("\" height=\"").appendInt(height)

src/main/java/uk/org/okapibarcode/output/SymbolRenderer.java

-15
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,4 @@ public interface SymbolRenderer {
3333
*/
3434
void render(Symbol symbol) throws IOException;
3535

36-
/**
37-
* Normalizes clockwise rotation values to 0, 90, 180, or 270 degrees.
38-
*
39-
* @param rotation the clockwise rotation to normalize
40-
* @return the normalized rotation (0, 90, 180, or 270)
41-
* @throws IllegalArgumentException if rotation is not a multiple of 90 degrees
42-
*/
43-
static int normalizeRotation(int rotation) {
44-
int normalized = ((rotation % 360) + 360) % 360;
45-
if (normalized % 90 != 0) {
46-
throw new IllegalArgumentException("Rotation must be a multiple of 90 degrees");
47-
}
48-
return normalized;
49-
}
50-
5136
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2024 Daniel Gredler
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package uk.org.okapibarcode.util;
18+
19+
/**
20+
* Integer utility class.
21+
*/
22+
public final class Integers {
23+
24+
private Integers() {
25+
// utility class
26+
}
27+
28+
/**
29+
* Normalizes rotation degree values to 0, 90, 180, or 270 degrees.
30+
*
31+
* @param rotation the rotation to normalize
32+
* @return the normalized rotation (0, 90, 180, or 270)
33+
* @throws IllegalArgumentException if rotation is not a multiple of 90 degrees
34+
*/
35+
public static int normalizeRotation(int rotation) {
36+
int normalized = ((rotation % 360) + 360) % 360;
37+
if (normalized % 90 != 0) {
38+
throw new IllegalArgumentException("Rotation must be a multiple of 90 degrees");
39+
}
40+
return normalized;
41+
}
42+
}

src/test/java/uk/org/okapibarcode/output/Java2DRendererTest.java

+5-11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package uk.org.okapibarcode.output;
1818

19+
import static uk.org.okapibarcode.util.Integers.normalizeRotation;
20+
1921
import java.awt.Font;
2022
import java.awt.GradientPaint;
2123
import java.awt.Graphics2D;
@@ -207,17 +209,9 @@ public void testCode93RotationMinus270() throws IOException {
207209
private static void test(Symbol symbol, String expectationFile, int rotation) throws IOException {
208210

209211
int magnification = 4;
210-
int w = symbol.getWidth() * magnification;
211-
int h = symbol.getHeight() * magnification;
212-
int normalizedRotation = SymbolRenderer.normalizeRotation(rotation);
213-
214-
switch (normalizedRotation) {
215-
case 90:
216-
case 270:
217-
w = symbol.getHeight() * magnification;
218-
h = symbol.getWidth() * magnification;
219-
break;
220-
}
212+
int rot = normalizeRotation(rotation);
213+
int w = magnification * (rot != 90 && rot != 270 ? symbol.getWidth() : symbol.getHeight());
214+
int h = magnification * (rot != 90 && rot != 270 ? symbol.getHeight() : symbol.getWidth());
221215

222216
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
223217
Graphics2D g2d = image.createGraphics();

src/test/java/uk/org/okapibarcode/output/SymbolRendererTest.java

-49
This file was deleted.

0 commit comments

Comments
 (0)