burrow/src/main/java/io/rudefox/cold/QRCode.java

111 lines
4.4 KiB
Java

package io.rudefox.cold;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
class QRCode {
private static final String FALLBACK_SET_STRING = "##";
static String toQRCode(String data) {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.MARGIN, 0);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
BitMatrix bitMatrix = null;
try {
bitMatrix = qrCodeWriter.encode(data, BarcodeFormat.QR_CODE, 0, 0, hints);
} catch (WriterException e) {
e.printStackTrace();
}
if (bitMatrix == null)
return "[Error Generating QR Code]";
if (charsetDoesNotSupportFullBlockChar())
return bitMatrix.toString(FALLBACK_SET_STRING, " ");
return toUTF8(bitMatrix);
}
private static String toUTF8(BitMatrix bitMatrix) {
char SPACE = '\u0020';
char LOWER_BLOCK = '\u2584';
char UPPER_BLOCK = '\u2580';
char FULL_BLOCK = '\u2588';
int[] blockCodepoints = new int[] {SPACE, LOWER_BLOCK, UPPER_BLOCK, FULL_BLOCK};
StringBuilder qrCode = new StringBuilder();
for (int y = 0; y < bitMatrix.getHeight(); y += 2) {
for (int x = 0; x < bitMatrix.getWidth(); x++) {
int upper_bit = bitMatrix.get(x, y) ? 1 : 0;
int lower_bit = y+1 < bitMatrix.getHeight() && bitMatrix.get(x, y+1) ? 1 : 0;
int index = upper_bit << 1 | lower_bit;
int blockCodepoint = blockCodepoints[index];
qrCode.appendCodePoint(blockCodepoint);
}
if (y < bitMatrix.getHeight() - 1)
qrCode.append("\n");
}
return qrCode.toString();
}
private static boolean charsetDoesNotSupportFullBlockChar() {
Charset charset = ServiceLocator.DEFAULT_CHARSET;
String charsetString = charset.toString();
return charset.equals(StandardCharsets.ISO_8859_1) ||
charset.equals(StandardCharsets.US_ASCII) ||
charsetString.equalsIgnoreCase("euc-jp") ||
charsetString.equalsIgnoreCase("euc-kr") ||
charsetString.equalsIgnoreCase("iso-2022-jp") ||
charsetString.equalsIgnoreCase("iso-8859-10") ||
charsetString.equalsIgnoreCase("iso-8859-13") ||
charsetString.equalsIgnoreCase("iso-8859-14") ||
charsetString.equalsIgnoreCase("iso-8859-15") ||
charsetString.equalsIgnoreCase("iso-8859-16") ||
charsetString.equalsIgnoreCase("iso-8859-2") ||
charsetString.equalsIgnoreCase("iso-8859-3") ||
charsetString.equalsIgnoreCase("iso-8859-4") ||
charsetString.equalsIgnoreCase("iso-8859-5") ||
charsetString.equalsIgnoreCase("iso-8859-6") ||
charsetString.equalsIgnoreCase("iso-8859-7") ||
charsetString.equalsIgnoreCase("iso-8859-8") ||
charsetString.equalsIgnoreCase("iso-8859-8-i") ||
charsetString.equalsIgnoreCase("macintosh") ||
charsetString.equalsIgnoreCase("shift_jis") ||
charsetString.equalsIgnoreCase("windows-1250") ||
charsetString.equalsIgnoreCase("windows-1251") ||
charsetString.equalsIgnoreCase("windows-1252") ||
charsetString.equalsIgnoreCase("windows-1253") ||
charsetString.equalsIgnoreCase("windows-1254") ||
charsetString.equalsIgnoreCase("windows-1255") ||
charsetString.equalsIgnoreCase("windows-1256") ||
charsetString.equalsIgnoreCase("windows-1257") ||
charsetString.equalsIgnoreCase("windows-1258") ||
charsetString.equalsIgnoreCase("windows-874") ||
charsetString.equalsIgnoreCase("x-mac-cyrillic") ||
charsetString.equalsIgnoreCase("x-user-defined");
}
}