152 lines
7.3 KiB
TypeScript
152 lines
7.3 KiB
TypeScript
import { Injectable } from '@angular/core';
|
|
import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
|
|
import { Rectangle, RedactionLogControllerService, SectionGrid, SectionRectangle } from '@redaction/red-ui-http';
|
|
import { hexToRgb } from '../../../utils/functions';
|
|
import { AppStateService } from '../../../state/app-state.service';
|
|
import { AnnotationWrapper } from '../../../models/file/annotation.wrapper';
|
|
import { UserPreferenceService } from '../../../services/user-preference.service';
|
|
|
|
@Injectable()
|
|
export class AnnotationDrawService {
|
|
constructor(
|
|
private readonly _appStateService: AppStateService,
|
|
private readonly _redactionLogControllerService: RedactionLogControllerService,
|
|
private readonly _userPreferenceService: UserPreferenceService
|
|
) {}
|
|
|
|
public drawAnnotations(activeViewer: WebViewerInstance, annotationWrappers: AnnotationWrapper[], hideSkipped: boolean = false) {
|
|
const annotations = [];
|
|
annotationWrappers.forEach((annotation) => {
|
|
annotations.push(this.computeAnnotation(activeViewer, annotation, hideSkipped));
|
|
});
|
|
|
|
const annotationManager = activeViewer.annotManager;
|
|
annotationManager.addAnnotations(annotations, { imported: true });
|
|
annotationManager.drawAnnotationsFromList(annotations);
|
|
|
|
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
|
this._redactionLogControllerService
|
|
.getSectionGrid(this._appStateService.activeProjectId, this._appStateService.activeFileId)
|
|
.subscribe((sectionGrid) => {
|
|
this.drawSections(activeViewer, sectionGrid);
|
|
});
|
|
}
|
|
}
|
|
|
|
public drawSections(activeViewer: WebViewerInstance, sectionGrid: SectionGrid) {
|
|
const sections = [];
|
|
for (const page of Object.keys(sectionGrid.rectanglesPerPage)) {
|
|
const sectionRectangles: SectionRectangle[] = sectionGrid.rectanglesPerPage[page];
|
|
sectionRectangles.forEach((sectionRectangle) => {
|
|
sections.push(this.computeSection(activeViewer, parseInt(page, 10), sectionRectangle));
|
|
// sectionRectangle.tableCells?.forEach(cell =>{
|
|
// sections.push(this.computeSection(activeViewer, parseInt(page, 10), cell));
|
|
// })
|
|
});
|
|
}
|
|
const annotationManager = activeViewer.annotManager;
|
|
annotationManager.addAnnotations(sections, { imported: true });
|
|
annotationManager.drawAnnotationsFromList(sections);
|
|
}
|
|
|
|
public computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: SectionRectangle) {
|
|
const rectangleAnnot = new activeViewer.Annotations.RectangleAnnotation();
|
|
const pageHeight = activeViewer.docViewer.getPageHeight(pageNumber);
|
|
const rectangle = {
|
|
topLeft: sectionRectangle.topLeft,
|
|
page: pageNumber,
|
|
height: sectionRectangle.height,
|
|
width: sectionRectangle.width
|
|
};
|
|
rectangleAnnot.PageNumber = pageNumber;
|
|
rectangleAnnot.X = rectangle.topLeft.x - 1;
|
|
rectangleAnnot.Y = pageHeight - (rectangle.topLeft.y + rectangle.height) - 1;
|
|
rectangleAnnot.Width = rectangle.width + 2;
|
|
rectangleAnnot.Height = rectangle.height + 2;
|
|
rectangleAnnot.ReadOnly = true;
|
|
rectangleAnnot.StrokeColor = this.getColor(activeViewer, 'analysis', 'analysis');
|
|
rectangleAnnot.StrokeThickness = 1;
|
|
|
|
return rectangleAnnot;
|
|
}
|
|
|
|
public computeAnnotation(activeViewer: WebViewerInstance, annotationWrapper: AnnotationWrapper, hideSkipped: boolean = false) {
|
|
const pageNumber = annotationWrapper.pageNumber;
|
|
const highlight = new activeViewer.Annotations.TextHighlightAnnotation();
|
|
highlight.PageNumber = pageNumber;
|
|
highlight.StrokeColor = this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.dictionary);
|
|
highlight.setContents(annotationWrapper.content);
|
|
highlight.Quads = this._rectanglesToQuads(annotationWrapper.positions, activeViewer, pageNumber);
|
|
highlight.Id = annotationWrapper.id;
|
|
highlight.ReadOnly = true;
|
|
// change log entries are drawn lighter
|
|
highlight.Opacity = annotationWrapper.isChangeLogRemoved ? 0.2 : 1;
|
|
highlight.Hidden = annotationWrapper.isChangeLogRemoved || (hideSkipped && annotationWrapper.isSkipped);
|
|
|
|
highlight.setCustomData('redaction', annotationWrapper.isRedacted);
|
|
highlight.setCustomData('skipped', annotationWrapper.isSkipped);
|
|
highlight.setCustomData('changeLog', annotationWrapper.isChangeLogEntry);
|
|
highlight.setCustomData('changeLogRemoved', annotationWrapper.isChangeLogRemoved);
|
|
highlight.setCustomData('redactionColor', this.getColor(activeViewer, 'redaction', 'redaction'));
|
|
highlight.setCustomData('annotationColor', this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.dictionary));
|
|
|
|
return highlight;
|
|
}
|
|
|
|
getColor(activeViewer: WebViewerInstance, superType: string, dictionary?: string) {
|
|
let color;
|
|
switch (superType) {
|
|
case 'hint':
|
|
case 'redaction':
|
|
case 'recommendation':
|
|
color = this._appStateService.getDictionaryColor(dictionary);
|
|
break;
|
|
case 'skipped':
|
|
color = this._appStateService.getDictionaryColor(superType);
|
|
break;
|
|
default:
|
|
color = this._appStateService.getDictionaryColor(superType);
|
|
break;
|
|
}
|
|
const rgbColor = hexToRgb(color);
|
|
return new activeViewer.Annotations.Color(rgbColor.r, rgbColor.g, rgbColor.b);
|
|
}
|
|
|
|
private _rectanglesToQuads(positions: Rectangle[], activeViewer: WebViewerInstance, pageNumber: number): any[] {
|
|
const pageHeight = activeViewer.docViewer.getPageHeight(pageNumber);
|
|
return positions.map((p) => this._rectangleToQuad(p, activeViewer, pageHeight));
|
|
}
|
|
|
|
private _rectangleToQuad(rectangle: Rectangle, activeViewer: WebViewerInstance, pageHeight: number): any {
|
|
const x1 = rectangle.topLeft.x;
|
|
const y1 = pageHeight - (rectangle.topLeft.y + rectangle.height);
|
|
|
|
const x2 = rectangle.topLeft.x + rectangle.width;
|
|
const y2 = pageHeight - (rectangle.topLeft.y + rectangle.height);
|
|
|
|
const x3 = rectangle.topLeft.x + rectangle.width;
|
|
const y3 = pageHeight - rectangle.topLeft.y;
|
|
|
|
const x4 = rectangle.topLeft.x;
|
|
const y4 = pageHeight - rectangle.topLeft.y;
|
|
|
|
return new activeViewer.CoreControls.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
|
}
|
|
|
|
public annotationToQuads(annotation: Annotations.Annotation, activeViewer: WebViewerInstance, pageNumber: number) {
|
|
const x1 = annotation.getRect().x1;
|
|
const y1 = annotation.getRect().y1 + annotation.getRect().getHeight();
|
|
|
|
const x2 = annotation.getRect().x1 + annotation.getRect().getWidth();
|
|
const y2 = annotation.getRect().y1 + annotation.getRect().getHeight();
|
|
|
|
const x3 = annotation.getRect().x1 + annotation.getRect().getWidth();
|
|
const y3 = annotation.getRect().y1;
|
|
|
|
const x4 = annotation.getRect().x1;
|
|
const y4 = annotation.getRect().y1;
|
|
|
|
return new activeViewer.CoreControls.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
|
}
|
|
}
|