Windows MetaFile under Oberonf 
Author Message
 Windows MetaFile under Oberonf

Does anyone know how to create a Windows(NT/95) MetaFile
under OberonF and how to paint then a graphic into the MetaFile?

I did so in C / Modula 2 but I don't know how to do the same with Oberonf /
Component Object Pascal.

Thanks for any information.

Jean-Yves Lalande

------------------------------------------------------------------------------
Jean-Yves Lalande --- Linguistic Data Processing --- University of Cologne

------------------------------------------------------------------------------



Sun, 05 Dec 1999 03:00:00 GMT  
 Windows MetaFile under Oberonf

Quote:
>Does anyone know how to create a Windows(NT/95) MetaFile
>under OberonF and how to paint then a graphic into the MetaFile?
>I did so in C / Modula 2 but I don't know how to do the same with Oberonf /
>Component Object Pascal.
>Thanks for any information.
>Jean-Yves Lalande
>------------------------------------------------------------------------------
>Jean-Yves Lalande --- Linguistic Data Processing --- University of Cologne

>------------------------------------------------------------------------------

Don't know whether it helps, anyway here is a module (distributed with the current release
of Linz Oberon V4) that displays metafiles as text elements.
I am very sure that you can do very similar things in Oberon/F.

MODULE MetaFileElems;   (* StCh, Oct-1-1996  *)

(* Class for Windows Meta Files and MetaFile - TextElements *)

IMPORT Win32, Kernel, S := SYSTEM, Printer, TextPrinter, Display, Oberon, Out, Files, Texts, TextFrames, Input;

CONST MMTEXT = 1; LOMETRIC = 2; HIMETRIC = 3; LOENGLISH = 4; HIENGLISH = 5;
                         ISOTROPIC = 7; ANISOTROPIC = 8;
                         CFMETAFILEPICT = 3;
                         NULL = 0;
                         CLIENTAREA = 100;                      (* default : 100 Units if no dimensions available *)
                         HORZRES = 8; HORZSIZE = 4;
                         VERTRES = 10; VERTSIZE = 6;

                         AlignLeft = 0;  AlignTop = 0;
                         (*AlignRight = 2;  AlignBottom = 8;
                         AlignCenter = 6; AlignBaseline = 24;*)

                         DUnit = LONG(TextFrames.Unit);
                         Unit300 = TextPrinter.Unit;
                         mm = TextFrames.mm;
                         frameW = 4;
                         ML =2;                

TYPE ADDRESS = LONGINT; HANDLE = LONGINT; HMETAFILE = HANDLE;
                HDC = HANDLE; LPSZ = LONGINT;

        (* constant header in clipboard, holds the handle of the metafile *)
        MetaFilePict = POINTER TO MetaFilePictDesc;
        MetaFilePictDesc = RECORD
                mm, xExt, yExt: LONGINT;
                handle: HMETAFILE;
        END;

        (* metafile class *)
        MetaFile* = POINTER TO MetaFileDesc;
        MetaFileDesc* = RECORD
                handle*: HMETAFILE;
                w*, h* : LONGINT;
                mm*: LONGINT;
                textAlign*: LONGINT;
        END;

        (* metafile text element *)
        Elem = POINTER TO ElemDesc;
        ElemDesc = RECORD (Texts.ElemDesc)
                mf: MetaFile;
        END;

        Rect = RECORD
                left, top, right, bottom: INTEGER
        END;

        APMHeader= RECORD
(*              key: LONGINT;*)                 (* not necessary, key is read seperately *)
                hmf: INTEGER;
                bbox: Rect;
                inch: INTEGER;
                reserved: LONGINT;
                checksum: INTEGER
        END;

        Frame = POINTER TO RECORD(Display.FrameDesc) e: Elem END;

(* global variables *)

VAR mod: LONGINT;
                Done: BOOLEAN;

        (* Windows specific API functions *)
        SaveDC: PROCEDURE (hdc: HDC): LONGINT;
        RestoreDC: PROCEDURE (hdc: HDC; nSavedDC: LONGINT): BOOLEAN;

        CreateMetaFile: PROCEDURE (filename: ADDRESS): HDC;
        CloseMetaFile: PROCEDURE (hdc: HDC): HMETAFILE;
        SetMetaFileBits: PROCEDURE (size: LONGINT; lpData: LONGINT): HMETAFILE;
        DeleteMetaFile: PROCEDURE (hmf: HMETAFILE);
        PlayMetaFile: PROCEDURE (hdc: HDC; hmf: HMETAFILE);
        GetMetaFile: PROCEDURE (szFileName: LONGINT): HMETAFILE;

        SetWindowOrg: PROCEDURE (hdc: HDC; x, y, lpPoint: LONGINT);
        SetWindowExt: PROCEDURE(hdc: HDC; nXExt, nYExt, lpPoint: LONGINT);

        SetMapMode: PROCEDURE (hdc: HDC; mapMode: LONGINT);
        SetViewportExt: PROCEDURE( hdc: HDC; nXExt, nYExt, lpSize : LONGINT);
        SetViewportOrg: PROCEDURE(hdc: HDC;  x, y, lpPoint : LONGINT);

        GetTempPath: PROCEDURE(len: LONGINT; path: LPSZ);
        GetWinTempFileName: PROCEDURE (path: LPSZ; prefix: LPSZ; unique: LONGINT; name: LPSZ);

PROCEDURE Order (VAR a, b: INTEGER);
        VAR swap: INTEGER;
BEGIN IF a > b THEN swap := a; a := b; b := swap END
END Order;

PROCEDURE DrawFrame (x1, y1, x2, y2: INTEGER);
BEGIN
        Order (x1, x2); Order (y1, y2);
        Display.ReplConst (Display.white, x1, y1, x2 - x1, 1, Display.invert);
        Display.ReplConst (Display.white, x1, y1, 1, y2 - y1, Display.invert);
        Display.ReplConst (Display.white, x1, y2, x2 - x1, 1, Display.invert);
        Display.ReplConst (Display.white, x2, y1, 1, y2 - y1, Display.invert)
END DrawFrame;

PROCEDURE Scale(val: LONGINT): LONGINT;
BEGIN
        RETURN val * DUnit DIV Unit300
END Scale;

(* prepare the device context for the display of the metafile *)
PROCEDURE (mf: MetaFile) PrepareDisp(hdc: HDC; x, y: LONGINT);
BEGIN
        SetMapMode(hdc, mf.mm);
        Win32.SetTextAlign(hdc, mf.textAlign);
        IF mf.mm = MMTEXT THEN
                SetWindowOrg(hdc, -x -(frameW DIV 2), -(Win32.DispH - y + (frameW DIV 2)), NULL)
        ELSIF (mf.mm = ISOTROPIC) OR (mf.mm = ANISOTROPIC) THEN
                SetWindowExt(hdc, Win32.DispW, Win32.DispH, NULL);
                IF mf.w = 0 THEN
                        (* no dimensions provided *)
                        SetViewportExt(hdc, CLIENTAREA, CLIENTAREA, NULL);
                        SetViewportOrg(hdc, x +(frameW DIV 2), Win32.DispH - y + (frameW DIV 2), NULL);
                ELSIF mf.w > 0 THEN
                        SetViewportExt(hdc, mf.w, mf.h, NULL);
                        SetViewportOrg(hdc, x +(frameW DIV 2), Win32.DispH - y + (frameW DIV 2), NULL);
                ELSIF mf.w < 0 THEN
                        (* not implemented yet *)
                END
        ELSE                    (* all metric coordinate systems *)
                SetViewportOrg(hdc, x + frameW DIV 2, Win32.DispH - y + frameW DIV 2, NULL)
        END
END PrepareDisp;

(* prepare the printer device context for the printing of the metafile
    the parameters (x,y) are 300dpi pixels, mf.w and mf.h are device dependant units *)
PROCEDURE (mf: MetaFile) PreparePrint(hdc: HDC; x,y: LONGINT);
        VAR dpi: INTEGER;               (* factor for adaption to 600 dpi *)
                W, H: LONGINT;
BEGIN
        IF Win32.Unit # Unit300 THEN dpi:=2 ELSE dpi :=1 END;           (* 300 dpi or 600 dpi ? *)

        SetMapMode(hdc, mf.mm);
        Win32.SetTextAlign(hdc, mf.textAlign);

        IF mf.mm = MMTEXT THEN                                  (* rescale in mode isotropic *)
                SetMapMode(hdc, ISOTROPIC);
                SetWindowExt(hdc, mf.w, mf.h, NULL);
                SetViewportExt(hdc, Scale(mf.w * dpi), Scale(mf.h * dpi), NULL)
        ELSIF (mf.mm = ISOTROPIC) OR (mf.mm = ANISOTROPIC) THEN
                SetWindowExt(hdc, Printer.PageWidth*dpi, Printer.PageHeight*dpi, NULL);
                IF mf.w = 0 THEN
                        W := Scale(CLIENTAREA); H := Scale(CLIENTAREA)
                ELSIF mf.w > 0 THEN
                        W := Scale(mf.w); H := Scale(mf.h)
                ELSE
                        (* not implemented yet *)
                END;
                SetViewportExt(hdc, W * dpi, H * dpi, NULL)
        END;            (* metric coordinate systems need no special code *)

        W := x + Scale(frameW DIV 2);
        H := Printer.PageHeight - y - Scale(frameW DIV 2) - Scale(mf.h);
        SetViewportOrg(hdc, W * dpi, H * dpi, NULL)
END PreparePrint;

PROCEDURE (mf: MetaFile) Draw*(x, y: LONGINT);
        VAR dc: HDC;
BEGIN
        IF mf.handle # NULL THEN
                dc := SaveDC(Win32.hdcDisp);
                IF dc # NULL THEN
                        mf.PrepareDisp(Win32.hdcDisp, x, y);
                        PlayMetaFile(Win32.hdcDisp, mf.handle);
                        Done := RestoreDC(Win32.hdcDisp, -1);
                        IF ~Done THEN HALT(255) END
                END
        END
END Draw;
PROCEDURE (mf: MetaFile) Print*(x, y: LONGINT);
        VAR dc: HDC;
BEGIN
        IF mf.handle # NULL THEN
                dc := SaveDC(Win32.PD.hdc);
                IF dc # NULL THEN
                        mf.PreparePrint(Win32.PD.hdc, x, y);
                        PlayMetaFile(Win32.PD.hdc, mf.handle);
                        Done := RestoreDC(Win32.PD.hdc, -1);
                        IF ~Done THEN HALT(255) END
                END
        END
END Print;

(* copy a metafile denoted by the handle 'mfh' into the object *)
PROCEDURE (mf: MetaFile) CopyMetaFile(mfh: HMETAFILE);
        VAR hdcMeta : HDC;
BEGIN
        hdcMeta := CreateMetaFile(NULL);
        PlayMetaFile(hdcMeta, mfh);
        mf.handle := CloseMetaFile(hdcMeta)
END CopyMetaFile;

PROCEDURE (mf: MetaFile) GetDimensions(hdc: HDC; mfh: MetaFilePict);
        CONST inch = 254;       (* 254 * 0,1 mm *)
BEGIN
        mf.w := mfh.xExt; mf.h := mfh.yExt; mf.mm := mfh.mm;
        IF (mf.mm = ISOTROPIC) OR (mf.mm = ANISOTROPIC) THEN
                IF mf.w = 0 THEN mf.w := CLIENTAREA*10 END;
                IF mf.h = 0 THEN mf.h := CLIENTAREA*10 END;
                mf.w := mf.w * Win32.GetDeviceCaps(hdc, HORZRES);
                mf.w := mf.w DIV Win32.GetDeviceCaps(hdc, HORZSIZE) DIV 100;
                mf.h := mf.h * Win32.GetDeviceCaps(hdc, VERTRES);
                mf.h := mf.h DIV Win32.GetDeviceCaps(hdc, VERTSIZE) DIV 100;
        ELSIF mf.mm = LOMETRIC THEN
                IF mf.w = 0 THEN mf.w := CLIENTAREA*10 END;
                IF mf.h = 0 THEN mf.h := CLIENTAREA*10 END;
                mf.w := mf.w * mm DIV 10 DIV DUnit;
                mf.h := mf.h * mm DIV 10 DIV DUnit
        ELSIF mf.mm = HIMETRIC THEN
                IF mf.w = 0 THEN mf.w := CLIENTAREA*100 END;
                IF mf.h = 0 THEN mf.h := CLIENTAREA*100 END;
                mf.w := mf.w * mm DIV 100 DIV DUnit;
                mf.h := mf.h * mm DIV 100 DIV DUnit
        ELSIF mf.mm = LOENGLISH THEN
                IF mf.w = 0 THEN mf.w := CLIENTAREA*inch END;
                IF mf.h = 0 THEN mf.h := CLIENTAREA*inch END;
                mf.w := mf.w * inch DIV 1000 * mm DIV DUnit;
                mf.h := mf.h * inch DIV 1000 * mm DIV DUnit
        ELSIF mf.mm = HIENGLISH THEN
                IF mf.w = 0 THEN mf.w := CLIENTAREA*inch*10 END;
                IF mf.h = 0 THEN mf.h := CLIENTAREA*inch*10 END;
                mf.w := mf.w * inch DIV 1000 * mm DIV 10 DIV DUnit;
                mf.h := mf.h * inch DIV 1000 * mm DIV 10 DIV DUnit
        ELSE (* MMTEXT assumed *)
                IF mf.w = 0 THEN mf.w := CLIENTAREA END;
                IF mf.h = 0 THEN mf.h := CLIENTAREA END
        END
END GetDimensions;

PROCEDURE Finalize(ptr: S.PTR);
        VAR mf: MetaFile;
BEGIN
        mf := S.VAL(MetaFile, ptr);
        DeleteMetaFile(mf.handle)
END Finalize;

PROCEDURE GetTempFileName(VAR nameTemp: ARRAY OF CHAR);
        VAR path: ARRAY 40 OF CHAR;
BEGIN
        GetTempPath(40, S.ADR(path));
        GetWinTempFileName(S.ADR(path), S.ADR("MF"), 0, S.ADR(nameTemp))
END GetTempFileName;

PROCEDURE GetFromClipboard(): MetaFile;
VAR adr, hMEM: LONGINT; mf: MetaFile; mfHeader: MetaFilePict;
BEGIN
        Done := Win32.OpenClipboard(Win32.Display);
        IF Done THEN    
                hMEM := Win32.GetClipboardData(CFMETAFILEPICT);
                IF hMEM # NULL THEN
                        (* metafile found in clipboard, now get handle *)
                        adr := Win32.GlobalLock(hMEM);
                        IF adr # NULL THEN
                                mfHeader := S.VAL(MetaFilePict, adr);
                                NEW(mf);
                                mf.CopyMetaFile(mfHeader.handle);
                                mf.GetDimensions(Win32.hdcDisp, mfHeader);
                                Kernel.RegisterObject(mf, Finalize);
                                Win32.GlobalUnlock(hMEM)
                        END
                END;
                Win32.CloseClipboard
        END;
        RETURN mf
END GetFromClipboard;
PROCEDURE GetFromFile(VAR fName: ARRAY OF CHAR): MetaFile;
CONST inch = 254;       (* 254 * 0,1 mm *)

VAR mf: MetaFile; handle: HMETAFILE; mfHeader: MetaFilePict;
                f: Files.File; key: ARRAY 4 OF S.BYTE; r: Files.Rider; len: LONGINT;
                apm: APMHeader; data: POINTER TO ARRAY OF S.BYTE;
BEGIN
        (* first check if it's a placeable metafile
...

read more »



Mon, 06 Dec 1999 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Nelco's Metafiles - Placeable Metafile Format .pmf - (Enhanced Metafile)

2. Windows MetaFile (WMF) support for Dolphin

3. VW 2.0 and Windows Metafiles

4. Problem with Windows metafiles (WMF) on Print Preview

5. VO 1.0c Windows metafiles

6. Help with WMF (Windows Metafile Format) and the ST/V Graphics Model

7. Windows metafiles in ST/V

8. OberonF/BlackBox: XYplane-output-window-size

9. OberonF: One copy at a time

10. OberonF: only 1 copy at a time

11. Wrapping controls: Black Box/ Component Pascal/ OberonF

12. Appending to files in OberonF/Component Pascal 1.2

 

 
Powered by phpBB® Forum Software