import { Platform } from 'react-native';
import type { CameraProps, Frame } from 'react-native-vision-camera';
import type { Barcode, Highlight, PointMapperFn, Size } from 'src/types';
import { computeBoundingBoxFromCornerPoints } from './convert';
import { applyScaleFactor, applyTransformation } from './geometry';
export const computeHighlights = (
barcodes: Barcode[],
frame: Pick,
layout: Size,
resizeMode: CameraProps['resizeMode'] = 'cover',
pointMapper?: PointMapperFn,
): Highlight[] => {
'worklet';
// If the layout is not yet known, we can't compute the highlights
if (layout.width === 0 || layout.height === 0) {
return [];
}
let adjustedLayout = {
width: layout.height,
height: layout.width,
};
if (Platform.OS === 'ios') {
/* iOS:
* "portrait" -> "landscape-right"
* "portrait-upside-down" -> "landscape-left"
* "landscape-left" -> "portrait"
* "landscape-right" -> "portrait-upside-down"
*/
// @NOTE destructure the object to make sure we don't hold a reference to the original layout
adjustedLayout = ['landscape-left'].includes(frame.orientation)
? {
width: layout.height,
height: layout.width,
}
: {
width: layout.width,
height: layout.height,
};
}
const highlights = barcodes.map((barcode, index) => {
const { value, cornerPoints } = barcode;
let translatedCornerPoints = cornerPoints;
translatedCornerPoints = translatedCornerPoints?.map((point) =>
applyScaleFactor(point, frame, adjustedLayout, resizeMode),
);
if (pointMapper) {
translatedCornerPoints = translatedCornerPoints?.map((point) =>
pointMapper(point, layout, frame.orientation),
);
} else {
translatedCornerPoints = translatedCornerPoints?.map((point) =>
applyTransformation(point, adjustedLayout, frame.orientation),
);
}
const valueFromCornerPoints = computeBoundingBoxFromCornerPoints(
translatedCornerPoints!,
);
return {
...barcode,
key: `${value}.${index}`,
cornerPoints: translatedCornerPoints,
boundingBox: valueFromCornerPoints,
};
});
// console.log(JSON.stringify(highlights, null, 2));
return highlights;
};