| 1 | unit GR32_Backends;
|
|---|
| 2 |
|
|---|
| 3 | (* ***** BEGIN LICENSE BLOCK *****
|
|---|
| 4 | * Version: MPL 1.1 or LGPL 2.1 with linking exception
|
|---|
| 5 | *
|
|---|
| 6 | * The contents of this file are subject to the Mozilla Public License Version
|
|---|
| 7 | * 1.1 (the "License"); you may not use this file except in compliance with
|
|---|
| 8 | * the License. You may obtain a copy of the License at
|
|---|
| 9 | * http://www.mozilla.org/MPL/
|
|---|
| 10 | *
|
|---|
| 11 | * Software distributed under the License is distributed on an "AS IS" basis,
|
|---|
| 12 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|---|
| 13 | * for the specific language governing rights and limitations under the
|
|---|
| 14 | * License.
|
|---|
| 15 | *
|
|---|
| 16 | * Alternatively, the contents of this file may be used under the terms of the
|
|---|
| 17 | * Free Pascal modified version of the GNU Lesser General Public License
|
|---|
| 18 | * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
|
|---|
| 19 | * of this license are applicable instead of those above.
|
|---|
| 20 | * Please see the file LICENSE.txt for additional information concerning this
|
|---|
| 21 | * license.
|
|---|
| 22 | *
|
|---|
| 23 | * The Original Code is Backend Extension for Graphics32
|
|---|
| 24 | *
|
|---|
| 25 | * The Initial Developer of the Original Code is
|
|---|
| 26 | * Andre Beckedorf - metaException
|
|---|
| 27 | * Andre@metaException.de
|
|---|
| 28 | *
|
|---|
| 29 | * Portions created by the Initial Developer are Copyright (C) 2007-2009
|
|---|
| 30 | * the Initial Developer. All Rights Reserved.
|
|---|
| 31 | *
|
|---|
| 32 | * Contributor(s):
|
|---|
| 33 | *
|
|---|
| 34 | * ***** END LICENSE BLOCK ***** *)
|
|---|
| 35 |
|
|---|
| 36 | interface
|
|---|
| 37 |
|
|---|
| 38 | {$I GR32.inc}
|
|---|
| 39 |
|
|---|
| 40 | uses
|
|---|
| 41 | {$IFDEF FPC}
|
|---|
| 42 | LCLIntf, LCLType, Types, Controls, Graphics,
|
|---|
| 43 | {$ELSE}
|
|---|
| 44 | Windows, Messages, Controls, Graphics,
|
|---|
| 45 | {$ENDIF}
|
|---|
| 46 | Classes, SysUtils, GR32, GR32_Containers, GR32_Image, GR32_Paths;
|
|---|
| 47 |
|
|---|
| 48 | type
|
|---|
| 49 | EBackend = class(Exception);
|
|---|
| 50 |
|
|---|
| 51 | ITextSupport = interface(IUnknown)
|
|---|
| 52 | ['{225997CC-958A-423E-8B60-9EDE0D3B53B5}']
|
|---|
| 53 | procedure Textout(X, Y: Integer; const Text: String); overload;
|
|---|
| 54 | procedure Textout(X, Y: Integer; const ClipRect: TRect; const Text: String); overload;
|
|---|
| 55 | procedure Textout(var DstRect: TRect; const Flags: Cardinal; const Text: String); overload;
|
|---|
| 56 | function TextExtent(const Text: String): TSize;
|
|---|
| 57 |
|
|---|
| 58 | procedure TextoutW(X, Y: Integer; const Text: Widestring); overload;
|
|---|
| 59 | procedure TextoutW(X, Y: Integer; const ClipRect: TRect; const Text: Widestring); overload;
|
|---|
| 60 | procedure TextoutW(var DstRect: TRect; const Flags: Cardinal; const Text: Widestring); overload;
|
|---|
| 61 | function TextExtentW(const Text: Widestring): TSize;
|
|---|
| 62 | end;
|
|---|
| 63 |
|
|---|
| 64 | IFontSupport = interface(IUnknown)
|
|---|
| 65 | ['{67C73044-1EFF-4FDE-AEA2-56BFADA50A48}']
|
|---|
| 66 | function GetOnFontChange: TNotifyEvent;
|
|---|
| 67 | procedure SetOnFontChange(Handler: TNotifyEvent);
|
|---|
| 68 | function GetFont: TFont;
|
|---|
| 69 | procedure SetFont(const Font: TFont);
|
|---|
| 70 |
|
|---|
| 71 | procedure UpdateFont;
|
|---|
| 72 | property Font: TFont read GetFont write SetFont;
|
|---|
| 73 | property OnFontChange: TNotifyEvent read GetOnFontChange write SetOnFontChange;
|
|---|
| 74 | end;
|
|---|
| 75 |
|
|---|
| 76 | ITextToPathSupport = interface(IUnknown)
|
|---|
| 77 | ['{6C4037E4-FF4D-4EE2-9C20-B9DB9C64B42D}']
|
|---|
| 78 | procedure TextToPath(Path: TCustomPath; const X, Y: TFloat; const Text: WideString); overload;
|
|---|
| 79 | procedure TextToPath(Path: TCustomPath; const DstRect: TFloatRect; const Text: WideString; Flags: Cardinal); overload;
|
|---|
| 80 | function MeasureText(const DstRect: TFloatRect; const Text: WideString; Flags: Cardinal): TFloatRect;
|
|---|
| 81 | end;
|
|---|
| 82 |
|
|---|
| 83 | ICanvasSupport = interface(IUnknown)
|
|---|
| 84 | ['{5ACFEEC7-0123-4AD8-8AE6-145718438E01}']
|
|---|
| 85 | function GetCanvasChange: TNotifyEvent;
|
|---|
| 86 | procedure SetCanvasChange(Handler: TNotifyEvent);
|
|---|
| 87 | function GetCanvas: TCanvas;
|
|---|
| 88 |
|
|---|
| 89 | procedure DeleteCanvas;
|
|---|
| 90 | function CanvasAllocated: Boolean;
|
|---|
| 91 |
|
|---|
| 92 | property Canvas: TCanvas read GetCanvas;
|
|---|
| 93 | property OnCanvasChange: TNotifyEvent read GetCanvasChange write SetCanvasChange;
|
|---|
| 94 | end;
|
|---|
| 95 |
|
|---|
| 96 | IDeviceContextSupport = interface(IUnknown)
|
|---|
| 97 | ['{DD1109DA-4019-4A5C-A450-3631A73CF288}']
|
|---|
| 98 | function GetHandle: HDC;
|
|---|
| 99 |
|
|---|
| 100 | procedure Draw(const DstRect, SrcRect: TRect; hSrc: HDC);
|
|---|
| 101 | procedure DrawTo(hDst: HDC; DstX, DstY: Integer); overload;
|
|---|
| 102 | procedure DrawTo(hDst: HDC; const DstRect, SrcRect: TRect); overload;
|
|---|
| 103 |
|
|---|
| 104 | property Handle: HDC read GetHandle;
|
|---|
| 105 | end;
|
|---|
| 106 |
|
|---|
| 107 | IBitmapContextSupport = interface(IUnknown)
|
|---|
| 108 | ['{DF0F9475-BA13-4C6B-81C3-D138624C4D08}']
|
|---|
| 109 | function GetBitmapInfo: TBitmapInfo;
|
|---|
| 110 | function GetBitmapHandle: THandle;
|
|---|
| 111 |
|
|---|
| 112 | property BitmapInfo: TBitmapInfo read GetBitmapInfo;
|
|---|
| 113 | property BitmapHandle: THandle read GetBitmapHandle;
|
|---|
| 114 | end;
|
|---|
| 115 |
|
|---|
| 116 | IPaintSupport = interface(IUnknown)
|
|---|
| 117 | ['{CE64DBEE-C4A9-4E8E-ABCA-1B1FD6F45924}']
|
|---|
| 118 | procedure ImageNeeded;
|
|---|
| 119 | procedure CheckPixmap;
|
|---|
| 120 | procedure DoPaint(ABuffer: TBitmap32; AInvalidRects: TRectList; ACanvas: TCanvas; APaintBox: TCustomPaintBox32);
|
|---|
| 121 | end;
|
|---|
| 122 |
|
|---|
| 123 | TRequireOperatorMode = (romAnd, romOr);
|
|---|
| 124 |
|
|---|
| 125 | // Helper functions to temporarily switch the back-end depending on the required interfaces
|
|---|
| 126 |
|
|---|
| 127 | procedure RequireBackendSupport(TargetBitmap: TCustomBitmap32;
|
|---|
| 128 | RequiredInterfaces: array of TGUID;
|
|---|
| 129 | Mode: TRequireOperatorMode; UseOptimizedDestructiveSwitchMethod: Boolean;
|
|---|
| 130 | out ReleasedBackend: TCustomBackend);
|
|---|
| 131 |
|
|---|
| 132 | procedure RestoreBackend(TargetBitmap: TCustomBitmap32; const SavedBackend: TCustomBackend);
|
|---|
| 133 |
|
|---|
| 134 | resourcestring
|
|---|
| 135 | RCStrCannotAllocateDIBHandle = 'Can''t allocate the DIB handle';
|
|---|
| 136 | RCStrCannotCreateCompatibleDC = 'Can''t create compatible DC';
|
|---|
| 137 | RCStrCannotSelectAnObjectIntoDC = 'Can''t select an object into DC';
|
|---|
| 138 |
|
|---|
| 139 | implementation
|
|---|
| 140 |
|
|---|
| 141 | procedure RequireBackendSupport(TargetBitmap: TCustomBitmap32;
|
|---|
| 142 | RequiredInterfaces: array of TGUID;
|
|---|
| 143 | Mode: TRequireOperatorMode; UseOptimizedDestructiveSwitchMethod: Boolean;
|
|---|
| 144 | out ReleasedBackend: TCustomBackend);
|
|---|
| 145 | var
|
|---|
| 146 | I: Integer;
|
|---|
| 147 | Supported: Boolean;
|
|---|
| 148 | begin
|
|---|
| 149 | Supported := False;
|
|---|
| 150 | for I := Low(RequiredInterfaces) to High(RequiredInterfaces) do
|
|---|
| 151 | begin
|
|---|
| 152 | Supported := Supports(TargetBitmap.Backend, RequiredInterfaces[I]);
|
|---|
| 153 | if ((Mode = romAnd) and not Supported) or
|
|---|
| 154 | ((Mode = romOr) and Supported) then
|
|---|
| 155 | Break;
|
|---|
| 156 | end;
|
|---|
| 157 |
|
|---|
| 158 | if not Supported then
|
|---|
| 159 | begin
|
|---|
| 160 | if UseOptimizedDestructiveSwitchMethod then
|
|---|
| 161 | TargetBitmap.SetSize(0, 0); // Reset size so we avoid the buffer copy during back-end switch
|
|---|
| 162 |
|
|---|
| 163 | ReleasedBackend := TargetBitmap.ReleaseBackend;
|
|---|
| 164 |
|
|---|
| 165 | // TODO: Try to find a back-end that supports the required interfaces
|
|---|
| 166 | // instead of resorting to the default platform back-end class...
|
|---|
| 167 | TargetBitmap.Backend := TargetBitmap.GetPlatformBackendClass.Create;
|
|---|
| 168 | end
|
|---|
| 169 | else
|
|---|
| 170 | ReleasedBackend := nil;
|
|---|
| 171 | end;
|
|---|
| 172 |
|
|---|
| 173 | procedure RestoreBackend(TargetBitmap: TCustomBitmap32; const SavedBackend: TCustomBackend);
|
|---|
| 174 | begin
|
|---|
| 175 | if Assigned(SavedBackend) then
|
|---|
| 176 | TargetBitmap.Backend := SavedBackend;
|
|---|
| 177 | end;
|
|---|
| 178 |
|
|---|
| 179 | end.
|
|---|