Here's the gist...
implementation
uses
...
const
ieVisionEmail: String = '...@datacad.com';
ieVisionSN: String = 'ievis-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx';
var
ieMultiBmp: TIEMultiBitmap;
procedure InitIEVision;
var
ErrMsg: String;
ieGlobalSettings: TIEGlobalSettings;
begin
//IEVisionSetSerialNumber(ieVisionEmail, ieVisionSN);
ieGlobalSettings := TIEGlobalSettings.Create(Application);
//ieGlobalSettings.RegisterPlugIns(); { Register all available plug-ins }
ieGlobalSettings.RegisterPlugIns([], ieVisionEmail, ieVisionSN); { Register all available plug-ins (IEVision User)}
//ieGlobalSettings.RegisterPlugIns([iepiIEVision], ieVisionEmail, ieVisionSN); { Register only IEVision}
//ieGlobalSettings.RegisterPlugIns([iepiPDFium]); { Register PDFium plug-in}
if not (iepiPDFium in ieGlobalSettings.ActivePlugIns) then
// Error
//ieGlobalSettings.RegisterPlugIns([iepiLanguages]);
if not (iepiLanguages in ieGlobalSettings.ActivePlugIns) then
// Error
else
ieGlobalSettings.MsgLanguage := msSystem;
ieGlobalSettings.Free;
//if not IEVisionAvailable() then begin
if not (iepiIEVision in ieGlobalSettings.ActivePlugIns) then begin
//ShowMessage( 'This application requires the ievision.dll plug-in, v' + IEVC_EXPECTED_LIBRARY_VERSION +'.' );
{ Cannot use ShowMessage at this point in the application startup process! }
ErrMsg := 'This application requires the ievision.dll plug-in, v' + IEVC_EXPECTED_LIBRARY_VERSION +'.';
Windows.MessageBox(0, PChar(ErrMsg), 'GUI Error', MB_SYSTEMMODAL or MB_SETFOREGROUND or MB_TOPMOST or MB_ICONHAND);
end;
end;
procedure CreateMultiBitmap;
begin
ieMultiBmp := TIEMultiBitmap.Create();
end;
procedure DestroyMultiBitmap;
begin
FreeAndNil(ieMultiBmp);
end;
procedure BitmapRegionIE(var DestDC: HDC; ImgFName: String; BmpFixedAspect: Boolean; Ang: aFloat; EntSize: uDgType.Point;
Pipe: Pipe_Type; aBmpLocation: TBmpLocation; BmpBoundary: TGPC_Polygon);
const
debug = False;
label
DoneSblt, Exit_MemFree, Exit_Select_Null_ClipRgn;
var
fdelta, ftop, fbot, ftopconst: aFloat;
nSrcHeight: Integer;
BmpPos: TMax2tpoints;
dx, dy, dw, dh, { Destination parameters }
sx, sy, sw, sh: Integer; { Source parameters }
WinPntsFull, WinPntsPartial: TMax2tpoints;
BmpBackClr: LongInt;
Rgn: HRGN;
br: HBRUSH;
SelClipRgn: Integer; { for return value }
vMin, vMax: TGPC_vertex;
ieBmp: TIEBitmap; { ImageEN }
ieCnv: TIECanvas; { Temporary canvas for ImageEN / Alpha }
Go, IsTransparent, Use_MM_LOENGLISH: Boolean;
TmpCnv: TCanvas; { For Printer }
ClipBox: TRect; { Extents of clipping region }
crTL, crBR, crTR, crBL: TPoint;
crWd, crHt: Integer;
pxTL, pxBR: TPoint;
pxWd, pxHt: Integer;
ImageID: Integer;
PDF_ImgTop, PDF_ImgLeft, PDF_ImgWidth, PDF_ImgHeight: Double;
RetVal: Integer;
BitmapStream: TStream;
i, ieIdx: Integer;
ieMultiBmp: TIEMultiBitmap;
function MakeBmpRegion: HRGN;
begin
if (BmpBoundary.NumContours = 0) then begin
Result := 0;
Exit;
end;
BeginPath(DestDC);
BmpBoundary.DL_Clip_Draw(Pipe, False, False, True, True, 1{, brClr, brOpa, BmpBrush});
EndPath(DestDC);
Result := PathToRegion(DestDC);
end;
function GetWindowPoint(pt: uDgType.Point): TPoint;
begin
if Pipe.ToPlotter then begin
Result.x := Round(pt.y);
Result.y := Round(pt.x);
end
else if (DCClipBoard.IsOpen) then begin
Result := DCClipBoard.ProcessPt(pt);
end
else begin
Result.x := MyRound(pt.x * CurrXfrm.xSc + CurrXfrm.xOff); { -32768 to 32767 }
Result.y := MyRound(pt.y * CurrXfrm.ySc + CurrXfrm.yOff); { -32768 to 32767 }
end;
end;
begin { BitmapRegionIE }
if Pipe.ToPlotter and Assigned(PrinterPDF) then begin
PrinterPDF.SaveState; { Save current clipping path (there should be none at this point). }
end;
Rgn := MakeBmpRegion;
if (Rgn = 0) then begin
Exit;
end;
if Pipe.ToPlotter or Pipe.ToClipboard then BmpBackClr := clWhite
else BmpBackClr := DrawFormColor;
(*
{ Load source image directly into ImageEN }
if FileExists(ImgFName) then begin
try
Go := True;
IsTransparent := False;
ieBmp := TIEBitmap.Create;
ieBmp.Read(ImgFName);
IsTransparent := ieBmp.HasAlphaChannel(True); { Validate - Is Alpha Channel Used? }
except
Go := False;
ieBmp.Free;
end;
end
else begin
Go := False;
end;
*)
Go := True;
{ ieMultiBmp created during initialization }
if (ieMultiBmp.Count > 0) then begin
for i := 0 to ieMultiBmp.Count - 1 do begin
if ImgFName = ieMultiBmp.ImageFilename[i] then begin { GetHash? }
ieBmp := ieMultiBmp.GetTIEBitmap(i);
ieIdx := i;
end
else begin
if FileExists(ImgFName) then begin
ieMultiBmp.AppendImage(ImgFname);
ieBmp := ieMultiBmp.GetTIEBitmap(ieMultiBmp.Count - 1);
ieIdx := ieMultiBmp.Count - 1;
end
else begin
Go := False;
end;
end;
end;
end
else begin
if FileExists(ImgFName) then begin
ieMultiBmp.AppendImage(ImgFname);
ieBmp := ieMultiBmp.GetTIEBitmap(ieMultiBmp.Count - 1);
ieIdx := ieMultiBmp.Count - 1;
end
else begin
Go := False;
end;
end;
if not Go then
goto Exit_Select_Null_ClipRgn; { Nothing to display - unable to get image }
IsTransparent := ieBmp.HasAlphaChannel(True); { Validate - Is Alpha Channel Used? }
if not UpdateBitmapForAspectRatioIE(ieBmp, EntSize, BmpFixedAspect) then
goto Exit_Select_Null_ClipRgn; { Nothing to display }
if (Ang <> 0) and (not RotateBitmapIE(ieBmp, Ang, BmpBackClr)) then
goto Exit_Select_Null_ClipRgn; { Nothing to display }
if BmpFixedAspect then
CheckUpdateAspectRatioIE(ieBmp, aBmpLocation);
BmpBoundary.GetClipMinMax(vMin, vMax);
aBmpLocation.ClipMin := BmpBoundary.MakePoint(vMin, 0);
aBmpLocation.ClipMax := BmpBoundary.MakePoint(vMax, 0);
if not CalcDisplayBitmapSizeIE(ieBmp, aBmpLocation, BmpPos) then
goto Exit_Select_Null_ClipRgn; { Nothing to display }
if not GetPartialBitmapIE(ieBmp, BmpPos[1], BmpPos[2], Pipe.ToPlotter) then
goto Exit_Select_Null_ClipRgn; { Nothing to display }
WinPntsFull[1] := GetWindowPoint(aBmpLocation.NoClipMin);
WinPntsFull[2] := GetWindowPoint(aBmpLocation.NoClipMax);
WinPntsPartial[1] := GetWindowPoint(aBmpLocation.ClipMin);
WinPntsPartial[2] := GetWindowPoint(aBmpLocation.ClipMax);
if Pipe.ToPlotter and (not RotateBitmapIE(ieBmp, cPi32, BmpBackClr)) then
goto Exit_Select_Null_ClipRgn; { Nothing to display }
if (DCClipBoard.IsOpen) and (not DCClipBoard.CurrentlyDrawing) then begin
goto Exit_Select_Null_ClipRgn;
end;
if (not Pipe.ToPlotter) and Pipe.ChkBrk then begin
Pipe.Brk := BrkPrss;
if (Pipe.Brk = -1) then goto Exit_Select_Null_ClipRgn;
end;
if not Pipe.ToPlotter and not IsTransparent then ieBmp.Flip(fdVertical); { Flip it }
BmpPos[1].x := 0;
BmpPos[1].y := 0;
BmpPos[2].x := ieBmp.Width;
BmpPos[2].y := ieBmp.Height;
sx := BmpPos[1].x;
sy := BmpPos[1].y;
sw := BmpPos[2].x;
sh := BmpPos[2].y;
dx := WinPntsPartial[1].x;
dw := (WinPntsPartial[2].x - WinPntsPartial[1].x) + 1;
dh := (WinPntsPartial[2].y - WinPntsPartial[1].y) + 1;
{ The SelectClipRgn function selects a region as the current clipping region for the specified device context. }
SelClipRgn := SelectClipRgn(DestDC, Rgn);
SelClipRgn := SelectClipRgn(MemCnv.Handle, Rgn);
GetClipBox(DestDC, ClipBox);
crTL := ClipBox.TopLeft;
crBR := ClipBox.BottomRight;
crTR.X := ClipBox.Right;
crTR.Y := ClipBox.Top;
crBL.X := ClipBox.Left;
crBL.Y := ClipBox.Bottom;
crWd := ClipBox.Right - ClipBox.Left;
crHt := ClipBox.Top - ClipBox.Bottom;
PDF_ImgLeft := crTL.X / 600;
PDF_ImgTop := crTL.Y / 600;
PDF_ImgHeight := Abs(crWd / 600);
PDF_ImgWidth := Abs(crHt / 600);
if (not Pipe.ToPlotter) then begin
if IsTransparent then begin
if ShowMemFrm then begin
ieCnv := TIECanvas.Create(MemFrm.Canvas);
SelClipRgn := SelectClipRgn(ieCnv.GDICanvas.Handle, Rgn);
end
else begin
ieCnv := TIECanvas.Create(MemCnv);
end;
Use_MM_LOENGLISH := False;
if Use_MM_LOENGLISH then begin { Alpha Blend does not work properly with this mapping mode }
ieBmp.Flip(fdVertical); { Flip it }
ieBmp.Resample(crWd, crHt);
ieBmp.DrawToCanvasWithAlpha(ieCnv.GDICanvas, crTL.X, crBR.Y);
end
else begin
{ Use Pixels }
pxTL := crTL;
pxBR := crBR;
LPtoDP(DestDC, pxTL, 1);
LPtoDP(DestDC, pxBR, 1);
pxWd := Abs(pxBR.X - pxTL.X);
pxHt := Abs(pxTL.Y - pxBR.Y);
if not ShowMemFrm then begin
SetMapMode(ieCnv.GDICanvas.Handle, MM_TEXT);
SetViewPortOrgEx(ieCnv.GDICanvas.Handle, 0, 0, nil);
end;
{ Resize AND Draw }
ieBmp.RenderToCanvasWithAlpha(ieCnv.GDICanvas, pxTL.X, pxTL.Y, pxWd, pxHt, 0, 0, ieBmp.Width, ieBmp.Height, 255, rfFastLinear, ielNormal, 1);
end;
ieCnv.Free;
end { if IsTransparent }
else begin
{ Resize AND Draw }
ieBmp.RenderToCanvas(MemCnv, crTL.X, crBR.Y, crWd, crHt, rfFastLinear, 0, DrawFormColor, True);
end;
Inc(NumVectorCount);
goto DoneSblt;
end; { not Pipe.ToPlotter }
TmpCnv := TCanvas.Create;
TmpCnv.Handle := DestDC; { Should be Printer or Metafile Preview }
{ Bitmap should not have been resized at this point... }
if DCADPrinter.CreatingPreview then begin
ieBmp.RenderToCanvas(TmpCnv, ClipBox, rfNone, 0, clWhite{DrawFormColor}, True);
end
else begin
ieBmp.Resample(ClipBox.Right - ClipBox.Left, ClipBox.Bottom - ClipBox.Top);
if IsTransparent then ieBmp.DrawToCanvasWithAlpha(TmpCnv, ClipBox.Left, ClipBox.Top)
else ieBmp.DrawToCanvas(TmpCnv, ClipBox.Left, ClipBox.Top);
end;
if Assigned(PrinterPDF) then begin
BitmapStream := TMemoryStream.Create;
if IsTransparent then ieBmp.Write(BitmapStream, ioPNG, nil)
else ieBmp.Write(BitmapStream, ioJPEG, nil);
ImageID := PrinterPDF.AddImageFromStream(BitmapStream, 6);
BitmapStream.Free;
if (ImageID <> 0) then begin
PrinterPDF.SelectImage(ImageID);
PrinterPDF.DrawImage(PDF_ImgLeft, PDF_ImgTop, PDF_ImgHeight, PDF_ImgWidth);
end;
PrinterPDF.LoadState; { Restore clipping path (there should be none after this point). }
end;
TmpCnv.Free;
DoneSblt:
if (not Pipe.ToPlotter) and (not Pipe.ToClipboard) then MyBitBlast;
Exit_MemFree:
//ieBmp.Free;
ieMultiBmp.ReleaseBitmap(ieIdx, False);
Exit_Select_Null_ClipRgn:
SelectClipRgn(DestDC, 0);
if (Rgn <> 0) then DeleteObject(Rgn);
end; { BitmapRegionIE }
initialization
InitIEVision;
CreateMultiBitmap;
finalization;
DestroyMultiBitmap;
end.