red-ui/apps/red-ui/src/app/modules/projects/services/annotation-draw.service.ts
2021-03-29 02:39:43 +03:00

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);
}
}