red-agate-barcode
Version:
red-agate barcode tag library.
121 lines (96 loc) • 4.09 kB
text/typescript
// Copyright (c) 2017, Shellyl_N and Authors
// license: ISC
// https://github.com/shellyln
import * as RedAgate from 'red-agate/modules/red-agate';
import { SvgCanvas,
SvgTextAttributes,
TextAlignValue,
TextBaselineValue } from 'red-agate-svg-canvas/modules/drawing/canvas/SvgCanvas';
import { Rect2D } from 'red-agate-svg-canvas/modules/drawing/canvas/TransferMatrix2D';
import { WebColor } from 'red-agate-svg-canvas/modules/drawing/canvas/WebColor';
import { CONTEXT_SVG_CANVAS } from 'red-agate/modules/red-agate/tags/Shape';
import { BarcodeBaseProps,
BarcodeBasePropsNoUndefined,
barcodeBasePropsDefault,
BarcodeBase } from './BarcodeBase';
import { charactersMap,
reverseMap,
fullAsciiMap } from './data/JapanPostal.data';
export interface JapanPostalProps extends BarcodeBaseProps {
elementWidth?: number;
}
export interface JapanPostalPropsNoUndefined extends BarcodeBasePropsNoUndefined {
elementWidth: number;
}
export const japanPostalPropsDefault: JapanPostalPropsNoUndefined = Object.assign({}, barcodeBasePropsDefault, {
elementWidth: 0.6,
height: 1.2 * 3
});
export class JapanPostal extends BarcodeBase<JapanPostalProps> {
public constructor(props: JapanPostalProps) {
super(Object.assign({}, japanPostalPropsDefault, props), charactersMap);
}
protected calcSymbolSize(
data: string, startChar: string, stopChar: string, cdChar: string
): {tw: number, th: number} {
const props = this.props as JapanPostalPropsNoUndefined;
// module width (bar + space)
const mw = props.elementWidth * 6;
return {
// total width (quiet + data + start + stop + cd)
tw: props.quietWidth * 2 + mw * 21 + props.elementWidth * (4 + 3),
// total height (quiet + bar)
th: props.quietHeight * 2 + props.height
};
}
protected calcCheckDigit(data: string): string {
let cdChar = "";
let cd = 0;
for (let i = 0; i < data.length; i++) {
const z = this.charactersMap.get(data[i]);
if (z === void 0) {
throw new Error("Japan Post: character is out of range.");
}
cd = (cd + z.index) % 19;
}
const cdch = reverseMap.get(cd);
if (cdch === void 0) {
throw new Error("Japan Post: check digit is out of range.");
}
cdChar = cdch;
return cdChar;
}
protected encodeData(data: string):
{data: string, heightData?: string, labelText?: string, startChar: string, stopChar: string} {
let d = "";
for (let i = 0; i < data.length; i++) {
const c = fullAsciiMap.get(data.charCodeAt(i));
if (c === void 0) {
throw new Error("Japan Post: character is out of range.");
}
d += c;
}
d += "DDDDDDDDDDDDDDDDD";
return {data: d.slice(0, 20), startChar: "[", stopChar: "]"};
}
protected getBarSpaceWidth(): number[] {
const props = this.props as JapanPostalPropsNoUndefined;
return [0, props.elementWidth];
}
protected getBarSpaceHeight(): Array<Array<{offset: number, height: number}>> {
const props = this.props as JapanPostalPropsNoUndefined;
const h = props.height;
return [
[{offset: 0, height: h }], // 0: space
[{offset: 0, height: h }], // 1: full
[{offset: 0, height: h * 2 / 3}], // 2: upper
[{offset: h / 3, height: h * 2 / 3}], // 3: lower
[{offset: h / 3, height: h / 3}] // 4: timing
];
}
protected get isHeightModulated(): boolean {
return true;
}
protected renderText(canvas: SvgCanvas, tw: number, th: number, data: string, text: string) {
}
}