unit Blend2D; { OPP wrappers for Blend2D C API. Follows the C++ API where possible. The following C++ classes are not converted because Delphi provides built-in alternatives for these: * BLArray: uses TArray instead * BLFile: uses TFileStream instead * BLString: uses String instead * BLVariant: not needed * BLStyle: style properties are used in another way. We may introduce a TBLStyle type once Delphi has support for managed records (or use Scope solution like TBLStrokeOptions). } {$SCOPEDENUMS ON} {$EXCESSPRECISION OFF} interface uses System.Math, System.SysUtils, Blend2D.Api; {$REGION 'Error Handling'} { ============================================================================ [Error Handling - Enums] ============================================================================ } type { Blend2D result code. } TBLResultCode = ( { Successful result code. } Success = BL_SUCCESS, { Out of memory [ENOMEM]. } OutOfMemory = BL_ERROR_OUT_OF_MEMORY, { Invalid value/argument [EINVAL]. } InvalidValue = BL_ERROR_INVALID_VALUE, { Invalid state [EFAULT]. } InvalidState = BL_ERROR_INVALID_STATE, { Invalid handle or file. [EBADF]. } InvalidHandle = BL_ERROR_INVALID_HANDLE, { Value too large [EOVERFLOW]. } ValueTooLarge = BL_ERROR_VALUE_TOO_LARGE, { Not initialized (some instance is built-in none when it shouldn't be). } NotInitialized = BL_ERROR_NOT_INITIALIZED, { Not implemented [ENOSYS]. } NotImplemented = BL_ERROR_NOT_IMPLEMENTED, { Operation not permitted [EPERM]. } NotPermitted = BL_ERROR_NOT_PERMITTED, { IO error [EIO]. } IOError = BL_ERROR_IO, { Device or resource busy [EBUSY]. } Busy = BL_ERROR_BUSY, { Operation interrupted [EINTR]. } Interrupted = BL_ERROR_INTERRUPTED, { Try again [EAGAIN]. } TryAgain = BL_ERROR_TRY_AGAIN, { Timed out [ETIMEDOUT]. } TimedOut = BL_ERROR_TIMED_OUT, { Broken pipe [EPIPE]. } BrokenPipe = BL_ERROR_BROKEN_PIPE, { File is not seekable [ESPIPE]. } InvalidSeek = BL_ERROR_INVALID_SEEK, { Too many levels of symlinks [ELOOP]. } SymlinkLoop = BL_ERROR_SYMLINK_LOOP, { File is too large [EFBIG]. } FileTooLarge = BL_ERROR_FILE_TOO_LARGE, { File/directory already exists [EEXIST]. } AlreadyExists = BL_ERROR_ALREADY_EXISTS, { Access denied [EACCES]. } AccessDenied = BL_ERROR_ACCESS_DENIED, { Media changed [Windows::ERROR_MEDIA_CHANGED]. } MediaChanged = BL_ERROR_MEDIA_CHANGED, { The file/FS is read-only [EROFS]. } ReadOnlyFS = BL_ERROR_READ_ONLY_FS, { Device doesn't exist [ENXIO]. } NoDevice = BL_ERROR_NO_DEVICE, { Not found, no entry (fs) [ENOENT]. } NoEntry = BL_ERROR_NO_ENTRY, { No media in drive/device [ENOMEDIUM]. } NoMedia = BL_ERROR_NO_MEDIA, { No more data / end of file [ENODATA]. } NoMoreData = BL_ERROR_NO_MORE_DATA, { No more files [ENMFILE]. } NoMoreFiles = BL_ERROR_NO_MORE_FILES, { No space left on device [ENOSPC]. } NoSpaceLeft = BL_ERROR_NO_SPACE_LEFT, { Directory is not empty [ENOTEMPTY]. } NotEmpty = BL_ERROR_NOT_EMPTY, { Not a file [EISDIR]. } NotFile = BL_ERROR_NOT_FILE, { Not a directory [ENOTDIR]. } NotDirectory = BL_ERROR_NOT_DIRECTORY, { Not same device [EXDEV]. } NotSameDevice = BL_ERROR_NOT_SAME_DEVICE, { Not a block device [ENOTBLK]. } NotBlockDevice = BL_ERROR_NOT_BLOCK_DEVICE, { File/path name is invalid [n/a]. } InvalidFilename = BL_ERROR_INVALID_FILE_NAME, { File/path name is too long [ENAMETOOLONG]. } FilenameTooLong = BL_ERROR_FILE_NAME_TOO_LONG, { Too many open files [EMFILE]. } TooManyOpenFiles = BL_ERROR_TOO_MANY_OPEN_FILES, { Too many open files by OS [ENFILE]. } TooManyOpenFilesByOS = BL_ERROR_TOO_MANY_OPEN_FILES_BY_OS, { Too many symbolic links on FS [EMLINK]. } TooManyLinks = BL_ERROR_TOO_MANY_LINKS, { Too many threads [EAGAIN]. } TooManyThreads = BL_ERROR_TOO_MANY_THREADS, { Thread pool is exhausted and couldn't acquire the requested thread count. } ThreadPoolExhausted = BL_ERROR_THREAD_POOL_EXHAUSTED, { File is empty (not specific to any OS error). } FileEmpty = BL_ERROR_FILE_EMPTY, { File open failed [Windows::ERROR_OPEN_FAILED]. } OpenFailed = BL_ERROR_OPEN_FAILED, { Not a root device/directory [Windows::ERROR_DIR_NOT_ROOT]. } NotRootDevice = BL_ERROR_NOT_ROOT_DEVICE, { Unknown system error that failed to translate to Blend2D result code. } UnknownSystemError = BL_ERROR_UNKNOWN_SYSTEM_ERROR, { Invalid data alignment. } InvalidArgument = BL_ERROR_INVALID_ALIGNMENT, { Invalid data signature or header. } InvalidSignature = BL_ERROR_INVALID_SIGNATURE, { Invalid or corrupted data. } InvalidData = BL_ERROR_INVALID_DATA, { Invalid string (invalid data of either UTF8, UTF16, or UTF32). } InvalidString = BL_ERROR_INVALID_STRING, { Truncated data (more data required than memory/stream provides). } DataTruncated = BL_ERROR_DATA_TRUNCATED, { Input data too large to be processed. } DataTooLarge = BL_ERROR_DATA_TOO_LARGE, { Decompression failed due to invalid data (RLE, Huffman, etc). } DecompressionFailed = BL_ERROR_DECOMPRESSION_FAILED, { Invalid geometry (invalid path data or shape). } InvalidGeometry = BL_ERROR_INVALID_GEOMETRY, { Returned when there is no matching vertex in path data. } NoMatchingVertex = BL_ERROR_NO_MATCHING_VERTEX, { No matching cookie (BLContext). } NoMatchingCookie = BL_ERROR_NO_MATCHING_COOKIE, { No states to restore (BLContext). } NoStatesToRestore = BL_ERROR_NO_STATES_TO_RESTORE, { The size of the image is too large. } ImageTooBig = BL_ERROR_IMAGE_TOO_LARGE, { Image codec for a required format doesn't exist. } ImageNoMatchingCodec = BL_ERROR_IMAGE_NO_MATCHING_CODEC, { Unknown or invalid file format that cannot be read. } ImageUnknownFileFormat = BL_ERROR_IMAGE_UNKNOWN_FILE_FORMAT, { Image codec doesn't support reading the file format. } ImageDecoderNotProvided = BL_ERROR_IMAGE_DECODER_NOT_PROVIDED, { Image codec doesn't support writing the file format. } ImageEncoderNotProvided = BL_ERROR_IMAGE_ENCODER_NOT_PROVIDED, { Multiple IHDR chunks are not allowed (PNG). } PngMultipleIHDR = BL_ERROR_PNG_MULTIPLE_IHDR, { Invalid IDAT chunk (PNG). } PngInvalidIDAT = BL_ERROR_PNG_INVALID_IDAT, { Invalid IEND chunk (PNG). } PngInvalidIEND = BL_ERROR_PNG_INVALID_IEND, { Invalid PLTE chunk (PNG). } PngInvalidPLTE = BL_ERROR_PNG_INVALID_PLTE, { Invalid tRNS chunk (PNG). } PngInvalidTRNS = BL_ERROR_PNG_INVALID_TRNS, { Invalid filter type (PNG). } PngInvalidFilter = BL_ERROR_PNG_INVALID_FILTER, { Unsupported feature (JPEG). } JpegUnsupportedFeature = BL_ERROR_JPEG_UNSUPPORTED_FEATURE, { Invalid SOS marker or header (JPEG). } JpegInvalidSOS = BL_ERROR_JPEG_INVALID_SOS, { Invalid SOF marker (JPEG). } JpegInvalidSOF = BL_ERROR_JPEG_INVALID_SOF, { Multiple SOF markers (JPEG). } JpegMultipleSOF = BL_ERROR_JPEG_MULTIPLE_SOF, { Unsupported SOF marker (JPEG). } JpegUnsupportedSOF = BL_ERROR_JPEG_UNSUPPORTED_SOF, { Font doesn't have any data as it's not initialized. } FontNotInitialized = BL_ERROR_FONT_NOT_INITIALIZED, { Font or font-face was not matched (BLFontManager). } FontNoMatch = BL_ERROR_FONT_NO_MATCH, { Font has no character to glyph mapping data. } FontNoCharacterMapping = BL_ERROR_FONT_NO_CHARACTER_MAPPING, { Font has missing an important table. } FontMissingImportantTable = BL_ERROR_FONT_MISSING_IMPORTANT_TABLE, { Font feature is not available. } FontFeatureNotAvailable = BL_ERROR_FONT_FEATURE_NOT_AVAILABLE, { Font has an invalid CFF data. } FontCFFInvalidData = BL_ERROR_FONT_CFF_INVALID_DATA, { Font program terminated because the execution reached the limit. } FontProgramTerminated = BL_ERROR_FONT_PROGRAM_TERMINATED, { Invalid glyph identifier. } InvalidGlyph = BL_ERROR_INVALID_GLYPH); type _TBLResultCodeHelper = record helper for TBLResultCode public function ToString: String; end; { ============================================================================ [Error Handling - Handlers] ============================================================================ } type { Type of exception that is raised for Blend2D errors. Exceptions are enabled by default, but can be disabled using BLSetErrorHandler. } EBlend2DError = class(Exception) {$REGION 'Internal Declarations'} private FResultCode: TBLResultCode; {$ENDREGION 'Internal Declarations'} public constructor Create(const AResultCode: TBLResultCode); { The Blend2D result code } property ResultCode: TBLResultCode read FResultCode; end; type { Type of procedure that is called when a Blend2D error occurs. Parameters: AResultCode: the Blend2D result code AUserData: any user data passed to BLSetErrorHandler. } TBLErrorHandler = procedure(const AResultCode: TBLResultCode; const AUserData: Pointer); { Sets a Blend2D error handler. Parameters: AHandler: the error handler that is called when a Blend2D error occurs. AUserData: any data you want to pass to the handler. The default error handler raises an exception of type EBlend2DError. You can disable error handling completely by setting AHandler to nil. In that case, there is no way to know if and when an error occured. The following procedures can be used to set some default error handlers: * BLSetExceptionErrorHandler: sets the error handler to a procedure that raises an exception when a Blend2D error occurs. This is the default behavior. * BLSetGetLastErrorHandler: sets the error handler to a procedure that sets a global error variable when a Blend2D error occurs. You can then use BLGetLastError to retrieve this error code. } procedure BLSetErrorHandler(const AHandler: TBLErrorHandler; const AUserData: Pointer); { Sets the error handler to a procedure that raises an exception when a Blend2D error occurs. This is the default behavior. } procedure BLSetExceptionErrorHandler; { Sets the error handler to a procedure that sets a global error variable when a Blend2D error occurs. You can then use BLGetLastError to retrieve this error code. } procedure BLSetGetLastErrorHandler; { Retrieves the last Blend2D error, or TBLResultCode.Success if there was none. After this call, the last error is reset to TBLResultCode.Success. This function should only be used when BLSetGetLastErrorHandler has been called. Otherwise, it always returns TBLResultCode.Success. This function is not thread-safe. If Blend2D is used from multiple threads, the returned value can be from any thread. } function BLGetLastError: TBLResultCode; {$ENDREGION 'Error Handling'} {$REGION 'General'} { ============================================================================ [General - Types] ============================================================================ } type { Tag is a 32-bit integer consisting of 4 characters in the following format: Tag := (A shl 24) or (B shl 16) or (C shl 8) or D Tags are used extensively by OpenType fonts and other binary formats like PNG. In most cases TAGs should only contain ASCII letters, digits, and spaces. Blend2D uses TBLTag in public and internal APIs to distinguish between a regular UInt32 and tag. } TBLTag = BLTag; type { Unique identifier that can be used for caching purposes. Some objects such as IBLImage and IBLFontFace have assigned an unique identifier that can be used to identify such objects for caching purposes. This identifier is never zero, so zero can be safely used as "uncached". Note: Unique identifier is per-process. It's implemented as an increasing global or thread-local counter in a way that identifiers would not collide. } TBLUniqueId = BLUniqueId; type { A type used to store a pack of bits. BitWord should be equal in size to a machine word. } TBLBitWord = BLBitWord; { ============================================================================ [General - Enums] ============================================================================ } type { Boolean operator. } TBLBooleanOp = ( { Result = B. } Copy = BL_BOOLEAN_OP_COPY, { Result = A and B. } &And = BL_BOOLEAN_OP_AND, { Result = A or B. } &Or = BL_BOOLEAN_OP_OR, { Result = A xor B. } &Xor = BL_BOOLEAN_OP_XOR, { Result = A and not B. } Sub = BL_BOOLEAN_OP_SUB); type { Extend mode. } TBLExtendMode = ( { Pad extend [default]. } Pad = BL_EXTEND_MODE_PAD, { Repeat extend. } &Repeat = BL_EXTEND_MODE_REPEAT, { Reflect extend. } Reflect = BL_EXTEND_MODE_REFLECT, { Alias to Pad. } PadXPadY = BL_EXTEND_MODE_PAD_X_PAD_Y, { Alias to Repeat. } RepeatXRepeatY = BL_EXTEND_MODE_REPEAT_X_REPEAT_Y, { Alias to Reflect. } ReflectXReflectY = BL_EXTEND_MODE_REFLECT_X_REFLECT_Y, { Pad X and repeat Y. } PadXRepeatY = BL_EXTEND_MODE_PAD_X_REPEAT_Y, { Pad X and reflect Y. } PadXReflectY = BL_EXTEND_MODE_PAD_X_REFLECT_Y, { Repeat X and pad Y. } RepeatXPadY = BL_EXTEND_MODE_REPEAT_X_PAD_Y, { Repeat X and reflect Y. } RepeatXReflectY = BL_EXTEND_MODE_REPEAT_X_REFLECT_Y, { Reflect X and pad Y. } ReflectXPadY = BL_EXTEND_MODE_REFLECT_X_PAD_Y, { Reflect X and repeat Y. } ReflectXRepeatY = BL_EXTEND_MODE_REFLECT_X_REPEAT_Y); type { Text encoding. } TBLTextEncoding = ( { UTF-8 encoding. } UTF8 = BL_TEXT_ENCODING_UTF8, { UTF-16 encoding (native endian). } UTF16 = BL_TEXT_ENCODING_UTF16, { UTF-32 encoding (native endian). } UTF32 = BL_TEXT_ENCODING_UTF32, { LATIN1 encoding (one byte per character). } Latin1 = BL_TEXT_ENCODING_LATIN1); { ============================================================================ [BLRange] ============================================================================ } type { Provides start and end indexes. It's used to specify a range of an operation related to indexed containers like IBLPath, IBLGradient, etc... } TBLRange = record {$REGION 'Internal Declarations'} private FHandle: BLRange; function GetFinish: Integer; inline; function GetStart: Integer; inline; procedure SetFinish(const AValue: Integer); inline; procedure SetStart(const AValue: Integer); inline; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLRange): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLRange): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AStart, AFinish: Integer); overload; inline; function Equals(const AOther: TBLRange): Boolean; inline; property Start: Integer read GetStart write SetStart; property Finish: Integer read GetFinish write SetFinish; end; PBLRange = ^TBLRange; function BLRange(const AStart, AFinish: Integer): TBLRange; inline; {$ENDREGION 'General'} {$REGION 'Array'} { ============================================================================ [BLArrayView] ============================================================================ } type { Array view } TBLArrayView = record public type P = ^T; {$REGION 'Internal Declarations'} private FHandle: BLArrayView; function GetLast: Pointer; inline; function GetLength: Integer; inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; overload; inline; procedure Reset(const AData: Pointer; const ALength: Integer); overload; inline; property Data: Pointer read FHandle.data; property First: Pointer read FHandle.data; property Last: Pointer read GetLast; property Length: Integer read GetLength; end; {$ENDREGION 'Array'} {$REGION 'Color'} { ============================================================================ [BLRgba32] ============================================================================ } type { 32-bit RGBA color (8-bit per component) stored as $AARRGGBB. } TBLRgba32 = record {$REGION 'Internal Declarations'} private FHandle: BLRgba32; function GetIsOpaque: Boolean; inline; function GetIsTransparent: Boolean; inline; {$ENDREGION 'Internal Declarations'} public class operator Implicit(const AValue: Cardinal): TBLRgba32; inline; static; class operator Implicit(const AValue: TBLRgba32): Cardinal; inline; static; class operator Equal(const ALeft, ARight: TBLRgba32): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLRgba32): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AValue: Cardinal); overload; inline; procedure Reset(const AR, AG, AB: Byte; const AA: Byte = 255); overload; inline; property R: Byte read FHandle.r write FHandle.r; property G: Byte read FHandle.g write FHandle.g; property B: Byte read FHandle.b write FHandle.b; property A: Byte read FHandle.a write FHandle.a; property Value: Cardinal read FHandle.value write FHandle.value; property IsOpaque: Boolean read GetIsOpaque; property IsTransparent: Boolean read GetIsTransparent; end; PBLRgba32 = ^TBLRgba32; function BLRgba32: TBLRgba32; overload; inline; function BLRgba32(const AValue: Cardinal): TBLRgba32; overload; inline; function BLRgba32(const AR, AG, AB: Byte; const AA: Byte = 255): TBLRgba32; overload; inline; { ============================================================================ [BLRgba64] ============================================================================ } type { 64-bit RGBA color (16-bit per component) stored as $AAAARRRRGGGGBBBB. } TBLRgba64 = record {$REGION 'Internal Declarations'} private FHandle: BLRgba64; function GetIsOpaque: Boolean; inline; function GetIsTransparent: Boolean; inline; {$ENDREGION 'Internal Declarations'} public class operator Implicit(const AValue: UInt64): TBLRgba64; inline; static; class operator Implicit(const AValue: TBLRgba64): UInt64; inline; static; class operator Equal(const ALeft, ARight: TBLRgba64): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLRgba64): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AValue: UInt64); overload; inline; procedure Reset(const AR, AG, AB: Word; const AA: Word = $FFFF); overload; inline; procedure Reset(const AValue: TBLRgba32); overload; inline; property R: Word read FHandle.r write FHandle.r; property G: Word read FHandle.g write FHandle.g; property B: Word read FHandle.b write FHandle.b; property A: Word read FHandle.a write FHandle.a; property Value: UInt64 read FHandle.value write FHandle.value; property IsOpaque: Boolean read GetIsOpaque; property IsTransparent: Boolean read GetIsTransparent; end; PBLRgba64 = ^TBLRgba64; function BLRgba64: TBLRgba64; overload; inline; function BLRgba64(const AValue: UInt64): TBLRgba64; overload; inline; function BLRgba64(const AR, AG, AB: Word; const AA: Word = $FFFF): TBLRgba64; overload; inline; function BLRgba64(const AValue: TBLRgba32): TBLRgba64; overload; inline; { ============================================================================ [BLRgba] ============================================================================ } type { 128-bit RGBA color stored as 4 32-bit floating point values in [RGBA] order. } TBLRgba = record {$REGION 'Internal Declarations'} private FHandle: BLRgba; function GetIsOpaque: Boolean; inline; function GetIsTransparent: Boolean; inline; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLRgba): Boolean; inline; static; class operator Equal(const ALeft: TBLRgba; const ARight: TBLRgba32): Boolean; inline; static; class operator Equal(const ALeft: TBLRgba; const ARight: TBLRgba64): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLRgba): Boolean; inline; static; class operator NotEqual(const ALeft: TBLRgba; const ARight: TBLRgba32): Boolean; inline; static; class operator NotEqual(const ALeft: TBLRgba; const ARight: TBLRgba64): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AR, AG, AB: Single; const AA: Single = 1); overload; inline; procedure Reset(const ARgba: TBLRgba32); overload; inline; procedure Reset(const ARgba: TBLRgba64); overload; inline; property R: Single read FHandle.r write FHandle.r; property G: Single read FHandle.g write FHandle.g; property B: Single read FHandle.b write FHandle.b; property A: Single read FHandle.a write FHandle.a; property IsOpaque: Boolean read GetIsOpaque; property IsTransparent: Boolean read GetIsTransparent; end; PBLRgba = ^TBLRgba; function BLRgba: TBLRgba; overload; inline; function BLRgba(const AR, AG, AB: Single; const AA: Single = 1): TBLRgba; overload; inline; function BLRgba(const ARgba: TBLRgba32): TBLRgba; overload; inline; function BLRgba(const ARgba: TBLRgba64): TBLRgba; overload; inline; type { Adds TBLRgba32 <-> TBLRgba64 <-> TBLRgba conversion } _TBLRgba32Helper = record helper for TBLRgba32 public procedure Reset(const AValue: TBLRgba64); overload; inline; procedure Reset(const AValue: TBLRgba); overload; inline; end; function BLRgba32(const AValue: TBLRgba64): TBLRgba32; overload; inline; function BLRgba32(const AValue: TBLRgba): TBLRgba32; overload; inline; type { Adds TBLRgba64 <-> TBLRgba conversion } _TBLRgba64Helper = record helper for TBLRgba64 public procedure Reset(const AValue: TBLRgba); overload; inline; end; function BLRgba64(const AValue: TBLRgba): TBLRgba32; overload; inline; {$ENDREGION 'Color'} {$REGION 'File System'} { ============================================================================ [Enums] ============================================================================ } type { File read flags used by IBLFileSystem.ReadFile. } TBLFileReadFlag = ( { Use memory mapping to read the content of the file. The destination buffer would be configured to use the memory mapped buffer instead of allocating its own. } MmapEnabled = 0, { Avoid memory mapping of small files. The size of small file is determined by Blend2D, however, you should expect it to be 16kB or 64kB depending on host operating system. } MmapAvoidSmall = 1, { Do not fallback to regular read if memory mapping fails. It's worth noting that memory mapping would fail for files stored on filesystem that is not local (like a mounted network filesystem, etc...). } MmapNoFallback = 3); TBLFileReadFlags = set of TBLFileReadFlag; {$ENDREGION 'File System'} {$REGION 'Geometry'} { ============================================================================ [Enums] ============================================================================ } type { Direction of a geometry used by geometric primitives and paths. } TBLGeometryDirection = ( { No direction specified. } None = BL_GEOMETRY_DIRECTION_NONE, { Clockwise direction. } CW = BL_GEOMETRY_DIRECTION_CW, { Counter-clockwise direction. } CCW = BL_GEOMETRY_DIRECTION_CCW); type { Geometry type. Geometry describes a shape or path that can be either rendered or added to a BLPath container. Both IBLPath and IBLContext provide functionality to work with all geometry types. Please note that each type provided here requires to pass a matching record to the function that consumes AGeometryType and AGeometryData arguments. } TBLGeometryType = ( { No geometry provided. } None = BL_GEOMETRY_TYPE_NONE, { TBLBoxI record. } BoxI = BL_GEOMETRY_TYPE_BOXI, { TBLBox record. } BoxD = BL_GEOMETRY_TYPE_BOXD, { TBLRectI record. } RectI = BL_GEOMETRY_TYPE_RECTI, { TBLRect record. } RectD = BL_GEOMETRY_TYPE_RECTD, { TBLCircle record. } Circle = BL_GEOMETRY_TYPE_CIRCLE, { TBLEllipse record. } Ellipse = BL_GEOMETRY_TYPE_ELLIPSE, { TBLRoundRect record. } RoundRect = BL_GEOMETRY_TYPE_ROUND_RECT, { TBLArc record. } Arc = BL_GEOMETRY_TYPE_ARC, { TBLArc record representing chord. } Chord = BL_GEOMETRY_TYPE_CHORD, { TBLArc record representing pie. } Pie = BL_GEOMETRY_TYPE_PIE, { TBLLine record. } Line = BL_GEOMETRY_TYPE_LINE, { TBLTriangle record. } Triangle = BL_GEOMETRY_TYPE_TRIANGLE, { TBLArrayView representing a polyline. } PolylineI = BL_GEOMETRY_TYPE_POLYLINEI, { TBLArrayView representing a polyline. } PolylineD = BL_GEOMETRY_TYPE_POLYLINED, { TBLArrayView representing a polygon. } PolygonI = BL_GEOMETRY_TYPE_POLYGONI, { TBLArrayView representing a polygon. } PolygonD = BL_GEOMETRY_TYPE_POLYGOND, { TBLArrayView record. } ArrayViewBoxI = BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, { TBLArrayView struct. } ArrayViewBoxD = BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, { TBLArrayView record. } ArrayviewRectI = BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, { TBLArrayView record. } ArrayViewRectD = BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, { IBLPath. } Path = BL_GEOMETRY_TYPE_PATH, { IBLRegion. } Region = BL_GEOMETRY_TYPE_REGION, { The last simple type. } SimpleLast = TBLGeometryType.Triangle); type { Fill rule. } TBLFillRule = ( { Non-zero fill-rule. } NonZero = BL_FILL_RULE_NON_ZERO, { Even-odd fill-rule. } EvenOdd = BL_FILL_RULE_EVEN_ODD); type { Hit-test result. } TBLHitTest = ( { Fully in. } FullyIn = BL_HIT_TEST_IN, { Partially in/out. } PartiallyIn = BL_HIT_TEST_PART, { Fully out. } FullyOut = BL_HIT_TEST_OUT, { Hit test failed (invalid argument, NaNs, etc). } Invalid = BL_HIT_TEST_INVALID); { ============================================================================ [BLPointI] ============================================================================ } type { Point specified as [x, y] using Integer as a storage type. } TBLPointI = record {$REGION 'Internal Declarations'} private FHandle: BLPointI; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLPointI): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLPointI): Boolean; inline; static; class operator Negative(const AValue: TBLPointI): TBLPointI; inline; static; class operator Add(const ALeft: TBLPointI; const ARight: Integer): TBLPointI; inline; static; class operator Add(const ALeft: Integer; const ARight: TBLPointI): TBLPointI; inline; static; class operator Add(const ALeft, ARight: TBLPointI): TBLPointI; inline; static; class operator Subtract(const ALeft: TBLPointI; const ARight: Integer): TBLPointI; inline; static; class operator Subtract(const ALeft: Integer; const ARight: TBLPointI): TBLPointI; inline; static; class operator Subtract(const ALeft, ARight: TBLPointI): TBLPointI; inline; static; class operator Multiply(const ALeft: TBLPointI; const ARight: Integer): TBLPointI; inline; static; class operator Multiply(const ALeft: Integer; const ARight: TBLPointI): TBLPointI; inline; static; class operator Multiply(const ALeft, ARight: TBLPointI): TBLPointI; inline; static; class operator IntDivide(const ALeft: TBLPointI; const ARight: Integer): TBLPointI; inline; static; class operator IntDivide(const ALeft: Integer; const ARight: TBLPointI): TBLPointI; inline; static; class operator IntDivide(const ALeft, ARight: TBLPointI): TBLPointI; inline; static; public procedure Reset; overload; inline; procedure Reset(const AX, AY: Integer); overload; inline; function Equals(const AOther: TBLPointI): Boolean; inline; property X: Integer read FHandle.x write FHandle.x; property Y: Integer read FHandle.y write FHandle.y; end; PBLPointI = ^TBLPointI; function BLPointI: TBLPointI; overload; inline; function BLPointI(const AX, AY: Integer): TBLPointI; overload; inline; { ============================================================================ [SizeI] ============================================================================ } type { Size specified as [w, h] using Integer as a storage type. } TBLSizeI = record {$REGION 'Internal Declarations'} private FHandle: BLSizeI; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLSizeI): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLSizeI): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AW, AH: Integer); overload; inline; function Equals(const AOther: TBLSizeI): Boolean; inline; property W: Integer read FHandle.w write FHandle.w; property H: Integer read FHandle.h write FHandle.h; end; PBLSizeI = ^TBLSizeI; function BLSizeI: TBLSizeI; overload; inline; function BLSizeI(const AW, AH: Integer): TBLSizeI; overload; inline; { ============================================================================ [BLBoxI] ============================================================================ } type { Box specified as [x0, y0, x1, y1] using Integer as a storage type. } TBLBoxI = record {$REGION 'Internal Declarations'} private FHandle: BLBoxI; function GetHeight: Integer; inline; function GetWidth: Integer; inline; procedure SetHeight(const AValue: Integer); inline; procedure SetWidth(const AValue: Integer); inline; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLBoxI): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLBoxI): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AX0, AY0, AX1, AY1: Integer); overload; inline; function Equals(const AOther: TBLBoxI): Boolean; inline; function Contains(const AX, AY: Integer): Boolean; overload; inline; function Contains(const AP: TBLPointI): Boolean; overload; inline; property X0: Integer read FHandle.x0 write FHandle.x0; property Y0: Integer read FHandle.y0 write FHandle.y0; property X1: Integer read FHandle.x1 write FHandle.x1; property Y1: Integer read FHandle.y1 write FHandle.y1; property Width: Integer read GetWidth write SetWidth; property Height: Integer read GetHeight write SetHeight; end; PBLBoxI = ^TBLBoxI; function BLBoxI: TBLBoxI; overload; inline; function BLBoxI(const AX0, AY0, AX1, AY1: Integer): TBLBoxI; overload; inline; { ============================================================================ [BLRectI] ============================================================================ } type { Rectangle specified as [x, y, w, h] using Integer as a storage type. } TBLRectI = record {$REGION 'Internal Declarations'} private FHandle: BLRectI; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLRectI): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLRectI): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AX, AY, AW, AH: Integer); overload; inline; function Equals(const AOther: TBLRectI): Boolean; inline; property X: Integer read FHandle.x write FHandle.x; property Y: Integer read FHandle.y write FHandle.y; property W: Integer read FHandle.w write FHandle.w; property H: Integer read FHandle.h write FHandle.h; end; PBLRectI = ^TBLRectI; function BLRectI: TBLRectI; overload; inline; function BLRectI(const AX, AY, AW, AH: Integer): TBLRectI; overload; inline; { ============================================================================ [BLPoint] ============================================================================ } type { Point specified as [x, y] using Double as a storage type. } TBLPoint = record {$REGION 'Internal Declarations'} private FHandle: BLPoint; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLPoint): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLPoint): Boolean; inline; static; class operator Negative(const AValue: TBLPoint): TBLPoint; inline; static; class operator Add(const ALeft: TBLPoint; const ARight: Double): TBLPoint; inline; static; class operator Add(const ALeft: Double; const ARight: TBLPoint): TBLPoint; inline; static; class operator Add(const ALeft, ARight: TBLPoint): TBLPoint; inline; static; class operator Subtract(const ALeft: TBLPoint; const ARight: Double): TBLPoint; inline; static; class operator Subtract(const ALeft: Double; const ARight: TBLPoint): TBLPoint; inline; static; class operator Subtract(const ALeft, ARight: TBLPoint): TBLPoint; inline; static; class operator Multiply(const ALeft: TBLPoint; const ARight: Double): TBLPoint; inline; static; class operator Multiply(const ALeft: Double; const ARight: TBLPoint): TBLPoint; inline; static; class operator Multiply(const ALeft, ARight: TBLPoint): TBLPoint; inline; static; class operator Divide(const ALeft: TBLPoint; const ARight: Double): TBLPoint; inline; static; class operator Divide(const ALeft: Double; const ARight: TBLPoint): TBLPoint; inline; static; class operator Divide(const ALeft, ARight: TBLPoint): TBLPoint; inline; static; public procedure Reset; overload; inline; procedure Reset(const AX, AY: Double); overload; inline; function Equals(const AOther: TBLPoint): Boolean; inline; property X: Double read FHandle.x write FHandle.x; property Y: Double read FHandle.y write FHandle.y; end; PBLPoint = ^TBLPoint; function BLPoint: TBLPoint; overload; inline; function BLPoint(const AX, AY: Double): TBLPoint; overload; inline; { ============================================================================ [Size] ============================================================================ } type { Size specified as [w, h] using Double as a storage type. } TBLSize = record {$REGION 'Internal Declarations'} private FHandle: BLSize; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLSize): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLSize): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AW, AH: Double); overload; inline; function Equals(const AOther: TBLSize): Boolean; inline; property W: Double read FHandle.w write FHandle.w; property H: Double read FHandle.h write FHandle.h; end; PBLSize = ^TBLSize; function BLSize: TBLSize; overload; inline; function BLSize(const AW, AH: Double): TBLSize; overload; inline; { ============================================================================ [BLBox] ============================================================================ } type { Box specified as [x0, y0, x1, y1] using Double as a storage type. } TBLBox = record {$REGION 'Internal Declarations'} private FHandle: BLBox; function GetWidth: Double; inline; procedure SetWidth(const AValue: Double); inline; function GetHeight: Double; inline; procedure SetHeight(const AValue: Double); inline; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLBox): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLBox): Boolean; inline; static; class operator Add(const ALeft: TBLBox; const ARight: Double): TBLBox; inline; static; class operator Add(const ALeft: Double; const ARight: TBLBox): TBLBox; inline; static; class operator Add(const ALeft: TBLBox; const ARight: TBLPoint): TBLBox; inline; static; class operator Add(const ALeft: TBLPoint; const ARight: TBLBox): TBLBox; inline; static; class operator Subtract(const ALeft: TBLBox; const ARight: Double): TBLBox; inline; static; class operator Subtract(const ALeft: Double; const ARight: TBLBox): TBLBox; inline; static; class operator Subtract(const ALeft: TBLBox; const ARight: TBLPoint): TBLBox; inline; static; class operator Subtract(const ALeft: TBLPoint; const ARight: TBLBox): TBLBox; inline; static; class operator Multiply(const ALeft: TBLBox; const ARight: Double): TBLBox; inline; static; class operator Multiply(const ALeft: Double; const ARight: TBLBox): TBLBox; inline; static; class operator Multiply(const ALeft: TBLBox; const ARight: TBLPoint): TBLBox; inline; static; class operator Multiply(const ALeft: TBLPoint; const ARight: TBLBox): TBLBox; inline; static; class operator Divide(const ALeft: TBLBox; const ARight: Double): TBLBox; inline; static; class operator Divide(const ALeft: Double; const ARight: TBLBox): TBLBox; inline; static; class operator Divide(const ALeft: TBLBox; const ARight: TBLPoint): TBLBox; inline; static; class operator Divide(const ALeft: TBLPoint; const ARight: TBLBox): TBLBox; inline; static; public procedure Reset; overload; inline; procedure Reset(const AX0, AY0, AX1, AY1: Double); overload; inline; function Equals(const AOther: TBLBox): Boolean; inline; function Contains(const AX, AY: Double): Boolean; overload; inline; function Contains(const AP: TBLPoint): Boolean; overload; inline; property X0: Double read FHandle.x0 write FHandle.x0; property Y0: Double read FHandle.y0 write FHandle.y0; property X1: Double read FHandle.x1 write FHandle.x1; property Y1: Double read FHandle.y1 write FHandle.y1; property Width: Double read GetWidth write SetWidth; property Height: Double read GetHeight write SetHeight; end; PBLBox = ^TBLBox; function BLBox: TBLBox; overload; inline; function BLBox(const AX0, AY0, AX1, AY1: Double): TBLBox; overload; inline; { ============================================================================ [BLRect] ============================================================================ } type { Rectangle specified as [x, y, w, h] using Double as a storage type. } TBLRect = record {$REGION 'Internal Declarations'} private FHandle: BLRect; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLRect): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLRect): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AX, AY, AW, AH: Double); overload; inline; function Equals(const AOther: TBLRect): Boolean; inline; property X: Double read FHandle.x write FHandle.x; property Y: Double read FHandle.y write FHandle.y; property W: Double read FHandle.w write FHandle.w; property H: Double read FHandle.h write FHandle.h; end; PBLRect = ^TBLRect; function BLRect: TBLRect; overload; inline; function BLRect(const AX, AY, AW, AH: Double): TBLRect; overload; inline; { ============================================================================ [BLLine] ============================================================================ } type { Line specified as [x0, y0, x1, y1] using Double as a storage type. } TBLLine = record {$REGION 'Internal Declarations'} private FHandle: BLLine; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLLine): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLLine): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AX0, AY0, AX1, AY1: Double); overload; inline; procedure Reset(const AP0, AP1: TBLPoint); overload; inline; function Equals(const AOther: TBLLine): Boolean; inline; property X0: Double read FHandle.x0 write FHandle.x0; property Y0: Double read FHandle.y0 write FHandle.y0; property X1: Double read FHandle.x1 write FHandle.x1; property Y1: Double read FHandle.y1 write FHandle.y1; end; PBLLine = ^TBLLine; function BLLine: TBLLine; overload; inline; function BLLine(const AX0, AY0, AX1, AY1: Double): TBLLine; overload; inline; function BLLine(const AP0, AP1: TBLPoint): TBLLine; overload; inline; { ============================================================================ [BLTriangle] ============================================================================ } type { Triangle data specified as [x0, y0, x1, y1, x2, y2] using Double as a storage type.} TBLTriangle = record {$REGION 'Internal Declarations'} private FHandle: BLTriangle; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLTriangle): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLTriangle): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AX0, AY0, AX1, AY1, AX2, AY2: Double); overload; inline; function Equals(const AOther: TBLTriangle): Boolean; inline; property X0: Double read FHandle.x0 write FHandle.x0; property Y0: Double read FHandle.y0 write FHandle.y0; property X1: Double read FHandle.x1 write FHandle.x1; property Y1: Double read FHandle.y1 write FHandle.y1; property X2: Double read FHandle.x2 write FHandle.x2; property Y2: Double read FHandle.y2 write FHandle.y2; end; PBLTriangle = ^TBLTriangle; function BLTriangle: TBLTriangle; overload; inline; function BLTriangle(const AX0, AY0, AX1, AY1, AX2, AY2: Double): TBLTriangle; overload; inline; { ============================================================================ [BLRoundRect] ============================================================================ } type { Rounded rectangle specified as [x, y, w, h, rx, ry] using Double as a storage type. } TBLRoundRect = record {$REGION 'Internal Declarations'} private FHandle: BLRoundRect; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLRoundRect): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLRoundRect): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const ARect: TBLRect; const AR: Double); overload; inline; procedure Reset(const ARect: TBLRect; const ARX, ARY: Double); overload; inline; procedure Reset(const AX, AY, AW, AH, AR: Double); overload; inline; procedure Reset(const AX, AY, AW, AH, ARX, ARY: Double); overload; inline; function Equals(const AOther: TBLRoundRect): Boolean; inline; property X: Double read FHandle.x write FHandle.x; property Y: Double read FHandle.y write FHandle.y; property W: Double read FHandle.w write FHandle.w; property H: Double read FHandle.h write FHandle.h; end; PBLRoundRect = ^TBLRoundRect; function BLRoundRect: TBLRoundRect; overload; inline; function BLRoundRect(const ARect: TBLRect; const AR: Double): TBLRoundRect; overload; inline; function BLRoundRect(const ARect: TBLRect; const ARX, ARY: Double): TBLRoundRect; overload; inline; function BLRoundRect(const AX, AY, AW, AH, AR: Double): TBLRoundRect; overload; inline; function BLRoundRect(const AX, AY, AW, AH, ARX, ARY: Double): TBLRoundRect; overload; inline; { ============================================================================ [BLCircle] ============================================================================ } type { Circle specified as [cx, cy, r] using Double as a storage type. } TBLCircle = record {$REGION 'Internal Declarations'} private FHandle: BLCircle; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLCircle): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLCircle): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const ACX, ACY, AR: Double); overload; inline; function Equals(const AOther: TBLCircle): Boolean; inline; property CX: Double read FHandle.cx write FHandle.cx; property CY: Double read FHandle.cy write FHandle.cy; property R: Double read FHandle.r write FHandle.r; end; PBLCircle = ^TBLCircle; function BLCircle: TBLCircle; overload; inline; function BLCircle(const ACX, ACY, AR: Double): TBLCircle; overload; inline; { ============================================================================ [BLEllipse] ============================================================================ } type { Ellipse specified as [cx, cy, rx, dy] using Double as a storage type. } TBLEllipse = record {$REGION 'Internal Declarations'} private FHandle: BLEllipse; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLEllipse): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLEllipse): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const ACX, ACY, ARX, ARY: Double); overload; inline; function Equals(const AOther: TBLEllipse): Boolean; inline; property CX: Double read FHandle.cx write FHandle.cx; property CY: Double read FHandle.cy write FHandle.cy; property RX: Double read FHandle.rx write FHandle.rx; property RY: Double read FHandle.ry write FHandle.ry; end; PBLEllipse = ^TBLEllipse; function BLEllipse: TBLEllipse; overload; inline; function BLEllipse(const ACX, ACY, ARX, ARY: Double): TBLEllipse; overload; inline; { ============================================================================ [BLArc] ============================================================================ } type { Arc specified as [cx, cy, rx, ry, start, sweep] using Double as a storage type. } TBLArc = record {$REGION 'Internal Declarations'} private FHandle: BLArc; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLArc): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLArc): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const ACX, ACY, AR, AStart, ASweep: Double); overload; inline; procedure Reset(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; inline; function Equals(const AOther: TBLArc): Boolean; inline; property CX: Double read FHandle.cx write FHandle.cx; property CY: Double read FHandle.cy write FHandle.cy; property RX: Double read FHandle.rx write FHandle.rx; property RY: Double read FHandle.ry write FHandle.ry; property Start: Double read FHandle.start write FHandle.start; property Sweep: Double read FHandle.sweep write FHandle.sweep; end; PBLArc = ^TBLArc; function BLArc: TBLArc; overload; inline; function BLArc(const ACX, ACY, AR, AStart, ASweep: Double): TBLArc; overload; inline; function BLArc(const ACX, ACY, ARX, ARY, AStart, ASweep: Double): TBLArc; overload; inline; { ============================================================================ [Globals Functions] ============================================================================ } function BLAbs(const AA: TBLPoint): TBLPoint; overload; inline; function BLAbs(const AA: TBLSize): TBLSize; overload; inline; function BLMin(const AA, AB: TBLPoint): TBLPoint; overload; inline; function BLMin(const AA: TBLPoint; const AB: Double): TBLPoint; overload; inline; function BLMin(const AA: Double; const AB: TBLPoint): TBLPoint; overload; inline; function BLMin(const AA, AB: TBLSize): TBLSize; overload; inline; function BLMax(const AA, AB: TBLPoint): TBLPoint; overload; inline; function BLMax(const AA: TBLPoint; const AB: Double): TBLPoint; overload; inline; function BLMax(const AA: Double; const AB: TBLPoint): TBLPoint; overload; inline; function BLMax(const AA, AB: TBLSize): TBLSize; overload; inline; function BLClamp(const AA: TBLPoint; const AB, AC: Double): TBLPoint; inline; {$ENDREGION 'Geometry'} {$REGION 'Matrix'} { ============================================================================ [BLMatrix2D - Enums] ============================================================================ } type { 2D matrix type that can be obtained by querying TBLMatrix2D.MatrixType. Identity Transl. Scale Swap Affine [1 0] [1 0] [. 0] [0 .] [. .] [0 1] [0 1] [0 .] [. 0] [. .] [0 0] [. .] [. .] [. .] [. .] } TBLMatrix2DType = ( { Identity matrix. } Identity = BL_MATRIX2D_TYPE_IDENTITY, { Has translation part (the rest is like identity). } Translate = BL_MATRIX2D_TYPE_TRANSLATE, { Has translation and scaling parts. } Scale = BL_MATRIX2D_TYPE_SCALE, { Has translation and scaling parts, however scaling swaps X/Y. } Swap = BL_MATRIX2D_TYPE_SWAP, { Generic affine matrix. } Affine = BL_MATRIX2D_TYPE_AFFINE, { Invalid/degenerate matrix not useful for transformations. } Invalid = BL_MATRIX2D_TYPE_INVALID); type { 2D matrix data index. } TBLMatrix2DValue = ( { Value at index 0 - M00. } M00 = BL_MATRIX2D_VALUE_00, { Value at index 1 - M01. } M01 = BL_MATRIX2D_VALUE_01, { Value at index 2 - M10. } M10 = BL_MATRIX2D_VALUE_10, { Value at index 3 - M11. } M11 = BL_MATRIX2D_VALUE_11, { Value at index 4 - M20. } M20 = BL_MATRIX2D_VALUE_20, { Value at index 5 - M21. } M21 = BL_MATRIX2D_VALUE_21); { ============================================================================ [BLMatrix2D] ============================================================================ } type { 2D matrix represents an affine transformation matrix that can be used to transform geometry and images. } TBLMatrix2D = record {$REGION 'Internal Declarations'} private FHandle: BLMatrix2D; function GetElement(const AIndex: TBLMatrix2DValue): Double; inline; procedure SetElement(const AIndex: TBLMatrix2DValue; const AValue: Double); inline; function GetMatrixType: TBLMatrix2DType; inline; function GetDeterminant: Double; inline; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLMatrix2D): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLMatrix2D): Boolean; inline; static; { Creates a new matrix initialized to identity. } class function MakeIdentity: TBLMatrix2D; inline; static; { Creates a new matrix initialized to translation. } class function MakeTranslation(const AX, AY: Double): TBLMatrix2D; overload; inline; static; class function MakeTranslation(const AP: TBLPoint): TBLMatrix2D; overload; inline; static; class function MakeTranslation(const AP: TBLPointI): TBLMatrix2D; overload; inline; static; { Creates a new matrix initialized to scaling. } class function MakeScaling(const AXY: Double): TBLMatrix2D; overload; inline; static; class function MakeScaling(const AX, AY: Double): TBLMatrix2D; overload; inline; static; class function MakeScaling(const AP: TBLPoint): TBLMatrix2D; overload; inline; static; class function MakeScaling(const AP: TBLPointI): TBLMatrix2D; overload; inline; static; { Creates a new matrix initialized to rotation, optional around point. } class function MakeRotation(const AAngle: Double): TBLMatrix2D; overload; inline; static; class function MakeRotation(const AAngle, AX, AY: Double): TBLMatrix2D; overload; inline; static; class function MakeRotation(const AAngle: Double; const AP: TBLPoint): TBLMatrix2D; overload; inline; static; { Create a new skewing matrix. } class function MakeSkewing(const AX, AY: Double): TBLMatrix2D; overload; inline; static; class function MakeSkewing(const AP: TBLPoint): TBLMatrix2D; overload; inline; static; { Create a new rotation matrix specified by ASin and ACos and optional translation. } class function MakeSinCos(const ASin, ACos: Double; const ATranslateX: Double = 0; const ATranslateY: Double = 0): TBLMatrix2D; overload; inline; static; class function MakeSinCos(const ASin, ACos: Double; const ATranslate: TBLPoint): TBLMatrix2D; overload; inline; static; { Inverts ASrc matrix and stores the result in ADst. Returns True if the matrix has been inverted successfully. } class function Invert(const ASrc: TBLMatrix2D; out ADst: TBLMatrix2D): Boolean; overload; inline; static; public { Resets matrix to identity. } procedure Reset; overload; inline; { Creates a new matrix initialized to: [m00 m01] [m10 m11] [m20 m21] } procedure Reset(const AM00, AM01, AM10, AM11, AM20, AM21: Double); overload; inline; { Resets matrix to translation. } procedure ResetToTranslation(const AX, AY: Double); overload; inline; procedure ResetToTranslation(const AP: TBLPoint); overload; inline; procedure ResetToTranslation(const AP: TBLPointI); overload; inline; { Resets matrix to scaling. } procedure ResetToScaling(const AXY: Double); overload; inline; procedure ResetToScaling(const AX, AY: Double); overload; inline; procedure ResetToScaling(const AP: TBLPoint); overload; inline; procedure ResetToScaling(const AP: TBLPointI); overload; inline; { Resets matrix to rotation, optional around point. } procedure ResetToRotation(const AAngle: Double); overload; procedure ResetToRotation(const AAngle, AX, AY: Double); overload; procedure ResetToRotation(const AAngle: Double; const AP: TBLPoint); overload; { Resets matrix to skewing. } procedure ResetToSkewing(const AX, AY: Double); overload; procedure ResetToSkewing(const AP: TBLPoint); overload; { Resets matrix to rotation specified by ASin and ACos and optional translation. } procedure ResetToSinCos(const ASin, ACos: Double; const ATranslateX: Double = 0; const ATranslateY: Double = 0); overload; inline; procedure ResetToSinCos(const ASin, ACos: Double; const ATranslate: TBLPoint); overload; inline; function Equals(const AOther: TBLMatrix2D): Boolean; inline; procedure Translate(const AX, AY: Double); overload; inline; procedure Translate(const AP: TBLPoint); overload; inline; procedure Translate(const AP: TBLPointI); overload; inline; procedure Scale(const AXY: Double); overload; inline; procedure Scale(const AX, AY: Double); overload; inline; procedure Scale(const AP: TBLPoint); overload; inline; procedure Scale(const AP: TBLPointI); overload; inline; procedure Rotate(const AAngle: Double); overload; procedure Rotate(const AAngle, AX, AY: Double); overload; procedure Rotate(const AAngle: Double; const AP: TBLPoint); overload; procedure Skew(const AX, AY: Double); overload; procedure Skew(const AP: TBLPoint); overload; procedure Transform(const AMatrix: TBLMatrix2D); procedure PostTranslate(const AX, AY: Double); overload; inline; procedure PostTranslate(const AP: TBLPoint); overload; inline; procedure PostTranslate(const AP: TBLPointI); overload; inline; procedure PostScale(const AXY: Double); overload; inline; procedure PostScale(const AX, AY: Double); overload; inline; procedure PostScale(const AP: TBLPoint); overload; inline; procedure PostScale(const AP: TBLPointI); overload; inline; procedure PostRotate(const AAngle: Double); overload; procedure PostRotate(const AAngle, AX, AY: Double); overload; procedure PostRotate(const AAngle: Double; const AP: TBLPoint); overload; procedure PostSkew(const AX, AY: Double); overload; procedure PostSkew(const AP: TBLPoint); overload; procedure PostTransform(const AMatrix: TBLMatrix2D); { Inverts the matrix, returns True if the matrix has been inverted successfully. } function Invert: Boolean; overload; function MapPoint(const AX, AY: Double): TBLPoint; overload; inline; function MapPoint(const AP: TBLPoint): TBLPoint; overload; inline; function MapVector(const AX, AY: Double): TBLPoint; overload; inline; function MapVector(const AV: TBLPoint): TBLPoint; overload; inline; property Elements[const AIndex: TBLMatrix2DValue]: Double read GetElement write SetElement; default; property M00: Double read FHandle.m00 write FHandle.m00; property M01: Double read FHandle.m01 write FHandle.m01; property M10: Double read FHandle.m10 write FHandle.m10; property M11: Double read FHandle.m11 write FHandle.m11; property M20: Double read FHandle.m20 write FHandle.m20; property M21: Double read FHandle.m21 write FHandle.m21; { The matrix type } property MatrixType: TBLMatrix2DType read GetMatrixType; { Calculates the matrix determinant. } property Determinant: Double read GetDeterminant; end; PBLMatrix2D = ^TBLMatrix2D; function BLMatrix2D: TBLMatrix2D; overload; inline; function BLMatrix2D(const AM00, AM01, AM10, AM11, AM20, AM21: Double): TBLMatrix2D; overload; inline; {$ENDREGION 'Matrix'} {$REGION 'Random'} { ============================================================================ [BLRandom] ============================================================================ } type { Simple pseudo random number generator. The current implementation uses a PRNG called `XORSHIFT+`, which has 64-bit seed, 128 bits of state, and full period `2^128 - 1`. Based on a paper by Sebastiano Vigna: http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf } TBLRandom = record {$REGION 'Internal Declarations'} private FHandle: BLRandom; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLRandom): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLRandom): Boolean; inline; static; public { Resets the random number generator to the given ASeed. } procedure Reset(const ASeed: UInt64 = 0); { Tests whether the random number generator is equivalent to AOther. Random number generator would only be equivalent to AOther if it was initialized from the same seed and has the same internal state. } function Equals(const AOther: TBLRandom): Boolean; inline; { Returns the next pseudo-random UInt64 value and advances its state. } function NextUInt64: UInt64; { Returns the next pseudo-random UInt32 value and advances its state. } function NextUInt32: UInt32; { Returns the next pseudo-random Double precision floating point in [0..1) range and advances its state. } function NextDouble: Double; end; PBLRandom = ^TBLRandom; {$ENDREGION 'Random'} {$REGION 'Gradient'} { ============================================================================ [BLGradient - Enums] ============================================================================ } type { Gradient type. } TBLGradientType = ( { Linear gradient type. } Linear = BL_GRADIENT_TYPE_LINEAR, { Radial gradient type. } Radial = BL_GRADIENT_TYPE_RADIAL, { Conical gradient type. } Conical = BL_GRADIENT_TYPE_CONICAL); type { Gradient data index. } TBLGradientValue = ( { x0 - start 'x' for Linear/Radial and center 'x' for Conical. } CommonX0 = BL_GRADIENT_VALUE_COMMON_X0, { y0 - start 'y' for Linear/Radial and center 'y' for Conical. } CommonY0 = BL_GRADIENT_VALUE_COMMON_Y0, { x1 - end 'x' for Linear/Radial. } CommonX1 = BL_GRADIENT_VALUE_COMMON_X1, { y1 - end 'y' for Linear/Radial. } CommonY1 = BL_GRADIENT_VALUE_COMMON_Y1, { Radial gradient r0 radius. } RadialR0 = BL_GRADIENT_VALUE_RADIAL_R0, {Conical gradient angle. } ConicalAngle = BL_GRADIENT_VALUE_CONICAL_ANGLE); { ============================================================================ [BLGradientStop] ============================================================================ } type { Defines an Offset and Rgba color that us used by IBLGradient to define a linear transition between colors. } TBLGradientStop = record {$REGION 'Internal Declarations'} private FHandle: BLGradientStop; function GetRgba: TBLRgba64; inline; procedure SetRgba(const AValue: TBLRgba64); inline; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLGradientStop): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLGradientStop): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AOffset: Double; const ARgba: TBLRgba32); overload; inline; procedure Reset(const AOffset: Double; const ARgba: TBLRgba64); overload; inline; function Equals(const AOther: TBLGradientStop): Boolean; inline; property Offset: Double read FHandle.offset write FHandle.offset; property Rgba: TBLRgba64 read GetRgba write SetRgba; end; PBLGradientStop = ^TBLGradientStop; function BLGradientStop(const AOffset: Double; const ARgba: TBLRgba32): TBLGradientStop; overload; inline; function BLGradientStop(const AOffset: Double; const ARgba: TBLRgba64): TBLGradientStop; overload; inline; { ============================================================================ [BLLinearGradientValues] ============================================================================ } type { Linear gradient values packed into a record. } TBLLinearGradientValues = record {$REGION 'Internal Declarations'} private FHandle: BLLinearGradientValues; {$ENDREGION 'Internal Declarations'} public procedure Reset; overload; inline; procedure Reset(const AX0, AY0, AX1, AY1: Double); overload; inline; property X0: Double read FHandle.x0 write FHandle.x0; property Y0: Double read FHandle.y0 write FHandle.y0; property X1: Double read FHandle.x1 write FHandle.x1; property Y1: Double read FHandle.y1 write FHandle.y1; end; PBLLinearGradientValues = ^TBLLinearGradientValues; function BLLinearGradientValues(const AX0, AY0, AX1, AY1: Double): TBLLinearGradientValues; inline; { ============================================================================ [BLRadialGradientValues] ============================================================================ } type { Radial gradient values packed into a record. } TBLRadialGradientValues = record {$REGION 'Internal Declarations'} private FHandle: BLRadialGradientValues; {$ENDREGION 'Internal Declarations'} public procedure Reset; overload; inline; procedure Reset(const AX0, AY0, AX1, AY1, AR0: Double); overload; inline; property X0: Double read FHandle.x0 write FHandle.x0; property Y0: Double read FHandle.y0 write FHandle.y0; property X1: Double read FHandle.x1 write FHandle.x1; property Y1: Double read FHandle.y1 write FHandle.y1; property R0: Double read FHandle.r0 write FHandle.r0; end; PBLRadialGradientValues = ^TBLRadialGradientValues; function BLRadialGradientValues(const AX0, AY0, AX1, AY1, AR0: Double): TBLRadialGradientValues; inline; { ============================================================================ [BLConicalGradientValues] ============================================================================ } type { Conical gradient values packed into a record. } TBLConicalGradientValues = record {$REGION 'Internal Declarations'} private FHandle: BLConicalGradientValues; {$ENDREGION 'Internal Declarations'} public procedure Reset; overload; inline; procedure Reset(const AX0, AY0, AAngle: Double); overload; inline; property X0: Double read FHandle.x0 write FHandle.x0; property Y0: Double read FHandle.y0 write FHandle.y0; property Angle: Double read FHandle.angle write FHandle.angle; end; PBLConicalGradientValues = ^TBLConicalGradientValues; function BLConicalGradientValues(const AX0, AY0, AAngle: Double): TBLConicalGradientValues; inline; { ============================================================================ [BLGradient] ============================================================================ } type { Gradient } IBLGradient = interface ['{804D20E0-8F67-415C-BD26-E56DC3BA4DDC}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetIsEmpty: Boolean; function GetGradientType: TBLGradientType; procedure SetGradientType(const AValue: TBLGradientType); function GetExtendMode: TBLExtendMode; procedure SetExtendMode(const AValue: TBLExtendMode); function GetValue(const AIndex: TBLGradientValue): Double; procedure SetValue(const AIndex: TBLGradientValue; const AValue: Double); function GetLinear: TBLLinearGradientValues; procedure SetLinear(const AValue: TBLLinearGradientValues); function GetRadial: TBLRadialGradientValues; procedure SetRadial(const AValue: TBLRadialGradientValues); function GetConical: TBLConicalGradientValues; procedure SetConical(const AValue: TBLConicalGradientValues); function GetX0: Double; procedure SetX0(const AValue: Double); function GetY0: Double; procedure SetY0(const AValue: Double); function GetX1: Double; procedure SetX1(const AValue: Double); function GetY1: Double; procedure SetY1(const AValue: Double); function GetR0: Double; procedure SetR0(const AValue: Double); function GetAngle: Double; procedure SetAngle(const AValue: Double); function GetSize: Integer; function GetCapacity: Integer; function GetAllStops: PBLGradientStop; function GetStop(const AIndex: Integer): TBLGradientStop; procedure SetStop(const AIndex: Integer; const AValue: TBLGradientStop); function GetHasMatrix: Boolean; function GetMatrixType: TBLMatrix2DType; function GetMatrix: TBLMatrix2D; procedure SetMatrix(const AValue: TBLMatrix2D); function GetHandle: PBLGradientCore; {$ENDREGION 'Internal Declarations'} procedure Initialize(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode = TBLExtendMode.Pad; const AStops: TArray = nil); overload; procedure Initialize(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode = TBLExtendMode.Pad; const AStops: TArray = nil); overload; procedure Initialize(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode = TBLExtendMode.Pad; const AStops: TArray = nil); overload; procedure Initialize(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); overload; procedure Initialize(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); overload; procedure Initialize(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); overload; procedure Reset; function Equals(const AOther: IBLGradient): Boolean; { Resets the gradient extend mode to TBLExtendMode.Pad. } procedure ResetExtendMode; procedure SetValues(const AIndex: TBLGradientValue; const AValues: TArray); overload; procedure SetValues(const AValues: TBLLinearGradientValues); overload; procedure SetValues(const AValues: TBLRadialGradientValues); overload; procedure SetValues(const AValues: TBLConicalGradientValues); overload; { Reserves the capacity of gradient for at least ACount stops. } procedure Reserve(const ACount: Integer); { Shrinks the capacity of gradient stops to fit the current usage. } procedure Shrink; procedure ResetStops; procedure SetStops(const AStops: TArray); procedure AddStop(const AOffset: Double; const ARgba: TBLRgba32); overload; procedure AddStop(const AOffset: Double; const ARgba: TBLRgba64); overload; procedure RemoveStop(const AIndex: Integer); procedure RemoveStopByOffset(const AOffset: Double; const AAll: Boolean = True); procedure RemoveStops(const ARange: TBLRange); procedure RemoveStopsByOffset(const AOffsetMin, AOffsetMax: Double); procedure ReplaceStop(const AIndex: Integer; const AOffset: Double; const ARgba: TBLRgba32); overload; procedure ReplaceStop(const AIndex: Integer; const AOffset: Double; const ARgba: TBLRgba64); overload; function IndexOfStop(const AOffset: Double): Integer; procedure ResetMatrix; procedure Translate(const AX, AY: Double); overload; procedure Translate(const AP: TBLPoint); overload; procedure Translate(const AP: TBLPointI); overload; procedure Scale(const AXY: Double); overload; procedure Scale(const AX, AY: Double); overload; procedure Scale(const AP: TBLPoint); overload; procedure Scale(const AP: TBLPointI); overload; procedure Skew(const AX, AY: Double); overload; procedure Skew(const AP: TBLPoint); overload; procedure Rotate(const AAngle: Double); overload; procedure Rotate(const AAngle, AX, AY: Double); overload; procedure Rotate(const AAngle: Double; const AP: TBLPoint); overload; procedure Rotate(const AAngle: Double; const AP: TBLPointI); overload; procedure Transform(const AMatrix: TBLMatrix2D); procedure PostTranslate(const AX, AY: Double); overload; procedure PostTranslate(const AP: TBLPoint); overload; procedure PostTranslate(const AP: TBLPointI); overload; procedure PostScale(const AXY: Double); overload; procedure PostScale(const AX, AY: Double); overload; procedure PostScale(const AP: TBLPoint); overload; procedure PostScale(const AP: TBLPointI); overload; procedure PostSkew(const AX, AY: Double); overload; procedure PostSkew(const AP: TBLPoint); overload; procedure PostRotate(const AAngle: Double); overload; procedure PostRotate(const AAngle, AX, AY: Double); overload; procedure PostRotate(const AAngle: Double; const AP: TBLPoint); overload; procedure PostRotate(const AAngle: Double; const AP: TBLPointI); overload; procedure PostTransform(const AMatrix: TBLMatrix2D); { Tests whether the gradient path is a built-in nil instance. } property IsNone: Boolean read GetIsNone; { Tests whether the gradient is empty. Empty gradient is considered any gradient that has no stops. } property IsEmpty: Boolean read GetIsEmpty; { The type of the gradient } property GradientType: TBLGradientType read GetGradientType write SetGradientType; { The gradient extend mode } property ExtendMode: TBLExtendMode read GetExtendMode write SetExtendMode; property Values[const AIndex: TBLGradientValue]: Double read GetValue write SetValue; property Linear: TBLLinearGradientValues read GetLinear write SetLinear; property Radial: TBLRadialGradientValues read GetRadial write SetRadial; property Conical: TBLConicalGradientValues read GetConical write SetConical; property X0: Double read GetX0 write SetX0; property Y0: Double read GetY0 write SetY0; property X1: Double read GetX1 write SetX1; property Y1: Double read GetY1 write SetY1; property R0: Double read GetR0 write SetR0; property Angle: Double read GetAngle write SetAngle; { The number of stops the gradient has. } property Size: Integer read GetSize; { The gradient capacity [in stops]. } property Capacity: Integer read GetCapacity; { The gradient stop data. } property AllStops: PBLGradientStop read GetAllStops; { A gradient stop at AIndex. } property Stops[const AIndex: Integer]: TBLGradientStop read GetStop write SetStop; property HasMatrix: Boolean read GetHasMatrix; property MatrixType: TBLMatrix2DType read GetMatrixType; property Matrix: TBLMatrix2D read GetMatrix write SetMatrix; { Internal handle for use with the C API } property Handle: PBLGradientCore read GetHandle; end; type { Implements IBLGradient } TBLGradient = class(TInterfacedObject, IBLGradient) {$REGION 'Internal Declarations'} private FHandle: BLGradientCore; FIsReference: Boolean; protected { IBLGradient } function GetIsNone: Boolean; function GetIsEmpty: Boolean; function GetGradientType: TBLGradientType; procedure SetGradientType(const AValue: TBLGradientType); function GetExtendMode: TBLExtendMode; procedure SetExtendMode(const AValue: TBLExtendMode); function GetValue(const AIndex: TBLGradientValue): Double; procedure SetValue(const AIndex: TBLGradientValue; const AValue: Double); function GetLinear: TBLLinearGradientValues; procedure SetLinear(const AValue: TBLLinearGradientValues); function GetRadial: TBLRadialGradientValues; procedure SetRadial(const AValue: TBLRadialGradientValues); function GetConical: TBLConicalGradientValues; procedure SetConical(const AValue: TBLConicalGradientValues); function GetX0: Double; procedure SetX0(const AValue: Double); function GetY0: Double; procedure SetY0(const AValue: Double); function GetX1: Double; procedure SetX1(const AValue: Double); function GetY1: Double; procedure SetY1(const AValue: Double); function GetR0: Double; procedure SetR0(const AValue: Double); function GetAngle: Double; procedure SetAngle(const AValue: Double); function GetSize: Integer; function GetCapacity: Integer; function GetAllStops: PBLGradientStop; function GetStop(const AIndex: Integer): TBLGradientStop; procedure SetStop(const AIndex: Integer; const AValue: TBLGradientStop); function GetHasMatrix: Boolean; function GetMatrixType: TBLMatrix2DType; function GetMatrix: TBLMatrix2D; procedure SetMatrix(const AValue: TBLMatrix2D); function GetHandle: PBLGradientCore; procedure Initialize(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode = TBLExtendMode.Pad; const AStops: TArray = nil); overload; procedure Initialize(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode = TBLExtendMode.Pad; const AStops: TArray = nil); overload; procedure Initialize(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode = TBLExtendMode.Pad; const AStops: TArray = nil); overload; procedure Initialize(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); overload; procedure Initialize(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); overload; procedure Initialize(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); overload; procedure Reset; function Equals(const AOther: IBLGradient): Boolean; reintroduce; overload; procedure ResetExtendMode; procedure SetValues(const AIndex: TBLGradientValue; const AValues: TArray); overload; procedure SetValues(const AValues: TBLLinearGradientValues); overload; procedure SetValues(const AValues: TBLRadialGradientValues); overload; procedure SetValues(const AValues: TBLConicalGradientValues); overload; procedure Reserve(const ACount: Integer); procedure Shrink; procedure ResetStops; procedure SetStops(const AStops: TArray); procedure AddStop(const AOffset: Double; const ARgba: TBLRgba32); overload; procedure AddStop(const AOffset: Double; const ARgba: TBLRgba64); overload; procedure RemoveStop(const AIndex: Integer); procedure RemoveStopByOffset(const AOffset: Double; const AAll: Boolean = True); procedure RemoveStops(const ARange: TBLRange); procedure RemoveStopsByOffset(const AOffsetMin, AOffsetMax: Double); procedure ReplaceStop(const AIndex: Integer; const AOffset: Double; const ARgba: TBLRgba32); overload; procedure ReplaceStop(const AIndex: Integer; const AOffset: Double; const ARgba: TBLRgba64); overload; function IndexOfStop(const AOffset: Double): Integer; procedure ResetMatrix; procedure Translate(const AX, AY: Double); overload; procedure Translate(const AP: TBLPoint); overload; procedure Translate(const AP: TBLPointI); overload; procedure Scale(const AXY: Double); overload; procedure Scale(const AX, AY: Double); overload; procedure Scale(const AP: TBLPoint); overload; procedure Scale(const AP: TBLPointI); overload; procedure Skew(const AX, AY: Double); overload; procedure Skew(const AP: TBLPoint); overload; procedure Rotate(const AAngle: Double); overload; procedure Rotate(const AAngle, AX, AY: Double); overload; procedure Rotate(const AAngle: Double; const AP: TBLPoint); overload; procedure Rotate(const AAngle: Double; const AP: TBLPointI); overload; procedure Transform(const AMatrix: TBLMatrix2D); procedure PostTranslate(const AX, AY: Double); overload; procedure PostTranslate(const AP: TBLPoint); overload; procedure PostTranslate(const AP: TBLPointI); overload; procedure PostScale(const AXY: Double); overload; procedure PostScale(const AX, AY: Double); overload; procedure PostScale(const AP: TBLPoint); overload; procedure PostScale(const AP: TBLPointI); overload; procedure PostSkew(const AX, AY: Double); overload; procedure PostSkew(const AP: TBLPoint); overload; procedure PostRotate(const AAngle: Double); overload; procedure PostRotate(const AAngle, AX, AY: Double); overload; procedure PostRotate(const AAngle: Double; const AP: TBLPoint); overload; procedure PostRotate(const AAngle: Double; const AP: TBLPointI); overload; procedure PostTransform(const AMatrix: TBLMatrix2D); private constructor Create(const AHandle: BLGradientCore; const AIsReference: Boolean); overload; {$ENDREGION 'Internal Declarations'} public constructor Create; overload; constructor Create(const AType: TBLGradientType; const AValues: PDouble = nil); overload; constructor Create(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode = TBLExtendMode.Pad; const AStops: TArray = nil); overload; constructor Create(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode = TBLExtendMode.Pad; const AStops: TArray = nil); overload; constructor Create(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode = TBLExtendMode.Pad; const AStops: TArray = nil); overload; constructor Create(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); overload; constructor Create(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); overload; constructor Create(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); overload; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; {$ENDREGION 'Gradient'} {$REGION 'Region'} { ============================================================================ [Enums] ============================================================================ } type { Region type. } TBLRegionType = ( { Region is empty (has no rectangles). } Empty = BL_REGION_TYPE_EMPTY, { Region has one rectangle (rectangular). } Rect = BL_REGION_TYPE_RECT, { Region has more YX sorted rectangles. } Complex = BL_REGION_TYPE_COMPLEX); { ============================================================================ [BLRegion] ============================================================================ } type TBLRegionView = TBLArrayView; type { 2D region. Region is a set of rectangles sorted and coalesced by their Y/X coordinates. } IBLRegion = interface ['{7AFAFA57-1358-490D-A984-4017EE9E3234}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetIsEmpty: Boolean; function GetRegionType: TBLRegionType; function GetIsRect: Boolean; function GetIsComplex: Boolean; function GetSize: Integer; function GetCapacity: Integer; function GetData: PBLBoxI; function GetDataEnd: PBLBoxI; function GetBoundingBox: TBLBoxI; function GetView: TBLRegionView; function GetHandle: PBLRegionCore; {$ENDREGION 'Internal Declarations'} procedure Reset; function Clone: IBLRegion; { Tests whether this region and the AOther region are equal. } function Equals(const AOther: IBLRegion): Boolean; procedure Assign(const ABox: TBLBoxI); overload; procedure Assign(const ABoxes: TArray); overload; procedure Assign(const ABoxes: PBLBoxI; const ACount: Integer); overload; procedure Assign(const ARect: TBLRectI); overload; procedure Assign(const ARects: TArray); overload; procedure Assign(const ARects: PBLRectI; const ACount: Integer); overload; procedure Clear; { Reserves at least ACount boxes in this region. } procedure Reserve(const ACount: Integer); { Shrinks the region data so it consumes only memory it requires. } procedure Shrink; procedure Combine(const ARegion: IBLRegion; const ABooleanOp: TBLBooleanOp); overload; procedure Combine(const ABox: TBLBoxI; const ABooleanOp: TBLBooleanOp); overload; { Translates the region by the given point APt. Possible overflow will be handled by clipping to a maximum region boundary, so the final region could be smaller than the region before translation. } procedure Translate(const APt: TBLPointI); { Translates the region by the given point APt and clip it to the given AClipBox. } procedure TranslateAndClip(const APt: TBLPointI; const AClipBox: TBLBoxI); overload; { Intersects the region with AR and clip it to the given AClipBox. } procedure IntersectAndClip(const AR: IBLRegion; const AClipBox: TBLBoxI); overload; { Tests if a given point APt or ABox is in region } function HitTest(const APt: TBLPointI): TBLHitTest; overload; function HitTest(const ABox: TBLBoxI): TBLHitTest; overload; { Tests whether the region is a built-in nil instance. } property IsNone: Boolean read GetIsNone; { Tests whether the region is empty. } property IsEmpty: Boolean read GetIsEmpty; { The type of the region } property RegionType: TBLRegionType read GetRegionType; { Tests whether the region is one rectangle. } property IsRect: Boolean read GetIsRect; { Tests whether the region is complex. } property IsComplex: Boolean read GetIsComplex; { The region size. } property Size: Integer read GetSize; { The region capacity. } property Capacity: Integer read GetCapacity; { Pointer to the region data. } property Data: PBLBoxI read GetData; { Pointer to the end of the region data. } property DataEnd: PBLBoxI read GetDataEnd; { The region's bounding box. } property BoundingBox: TBLBoxI read GetBoundingBox; { The region data as TBLRegionView. } property View: TBLRegionView read GetView; { Internal handle for use with the C API } property Handle: PBLRegionCore read GetHandle; end; type { Implements IBLRegion } TBLRegion = class(TInterfacedObject, IBLRegion) {$REGION 'Internal Declarations'} private FHandle: BLRegionCore; protected { IBLRegion } function GetIsNone: Boolean; function GetIsEmpty: Boolean; function GetRegionType: TBLRegionType; function GetIsRect: Boolean; function GetIsComplex: Boolean; function GetSize: Integer; function GetCapacity: Integer; function GetData: PBLBoxI; function GetDataEnd: PBLBoxI; function GetBoundingBox: TBLBoxI; function GetView: TBLRegionView; function GetHandle: PBLRegionCore; procedure Reset; function Clone: IBLRegion; function Equals(const AOther: IBLRegion): Boolean; reintroduce; overload; procedure Assign(const ABox: TBLBoxI); overload; procedure Assign(const ABoxes: TArray); overload; procedure Assign(const ABoxes: PBLBoxI; const ACount: Integer); overload; procedure Assign(const ARect: TBLRectI); overload; procedure Assign(const ARects: TArray); overload; procedure Assign(const ARects: PBLRectI; const ACount: Integer); overload; procedure Clear; procedure Reserve(const ACount: Integer); procedure Shrink; procedure Combine(const ARegion: IBLRegion; const ABooleanOp: TBLBooleanOp); overload; procedure Combine(const ABox: TBLBoxI; const ABooleanOp: TBLBooleanOp); overload; procedure Translate(const APt: TBLPointI); overload; procedure TranslateAndClip(const APt: TBLPointI; const AClipBox: TBLBoxI); overload; procedure IntersectAndClip(const AR: IBLRegion; const AClipBox: TBLBoxI); overload; function HitTest(const APt: TBLPointI): TBLHitTest; overload; function HitTest(const ABox: TBLBoxI): TBLHitTest; overload; {$ENDREGION 'Internal Declarations'} public constructor Create; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; public class function Combine(const AA, AB: IBLRegion; const ABooleanOp: TBLBooleanOp): IBLRegion; overload; static; class function Combine(const AA: IBLRegion; const AB: TBLBoxI; const ABooleanOp: TBLBooleanOp): IBLRegion; overload; static; class function Combine(const AA: TBLBoxI; const AB: IBLRegion; const ABooleanOp: TBLBooleanOp): IBLRegion; overload; static; class function Combine(const AA, AB: TBLBoxI; const ABooleanOp: TBLBooleanOp): IBLRegion; overload; static; class function Translate(const AR: IBLRegion; const APt: TBLPointI): IBLRegion; overload; static; class function TranslateAndClip(const AR: IBLRegion; const APt: TBLPointI; const AClipBox: TBLBoxI): IBLRegion; overload; static; class function IntersectAndClip(const AA, AB: IBLRegion; const AClipBox: TBLBoxI): IBLRegion; overload; static; end; {$ENDREGION 'Region'} {$REGION 'Path'} { ============================================================================ [Enums] ============================================================================ } type { Path command. } TBLPathCmd = ( { Move-to command (starts a new figure). } Move = BL_PATH_CMD_MOVE, { On-path command (interpreted as line-to or the end of a curve). } &On = BL_PATH_CMD_ON, { Quad-to control point. } Quad = BL_PATH_CMD_QUAD, { Cubic-to control point (always used as a pair of commands). } Cubic = BL_PATH_CMD_CUBIC, { Close path. } Close = BL_PATH_CMD_CLOSE); PBLPathCmd = ^TBLPathCmd; type { Path flags. } TBLPathFlag = ( { Path is empty (no commands or close commands only). } Empty = 0, { Path contains multiple figures. } Multiple = 1, { Path contains quad curves (at least one). } Quads = 2, { Path contains cubic curves (at least one). } Cubics = 3, { Path is invalid. } Invalid = 30, { Flags are dirty (not reflecting the current status). } Dirty = 31); TBLPathFlags = set of TBLPathFlag; type { Path reversal mode. } TBLPathReverseMode = ( { Reverse each figure and their order as well (default). } Complete = BL_PATH_REVERSE_MODE_COMPLETE, { Reverse each figure separately (keeps their order). } Separate = BL_PATH_REVERSE_MODE_SEPARATE); type { Stroke join type. } TBLStrokeJoin = ( { Miter-join possibly clipped at MiterLimit [default]. } MiterClip = BL_STROKE_JOIN_MITER_CLIP, { Miter-join or bevel-join depending on MiterLimit condition. } MiterBevel = BL_STROKE_JOIN_MITER_BEVEL, { Miter-join or round-join depending on MiterLimit condition. } MiterRound = BL_STROKE_JOIN_MITER_ROUND, { Bevel-join. } Bevel = BL_STROKE_JOIN_BEVEL, { Round-join. } Round = BL_STROKE_JOIN_ROUND); type { Position of a stroke-cap. } TBLStrokeCapPosition = ( { Start of the path. } Start = BL_STROKE_CAP_POSITION_START, { End of the path. } Finish = BL_STROKE_CAP_POSITION_END); type { A presentation attribute defining the shape to be used at the end of open subpaths. } TBLStrokeCap = ( { Butt cap [default]. } Butt = BL_STROKE_CAP_BUTT, { Square cap. } Square = BL_STROKE_CAP_SQUARE, { Round cap. } Round = BL_STROKE_CAP_ROUND, { Round cap reversed. } RoundRev = BL_STROKE_CAP_ROUND_REV, { Triangle cap. } Triangle = BL_STROKE_CAP_TRIANGLE, { Triangle cap reversed. } TriangleRev = BL_STROKE_CAP_TRIANGLE_REV); type { Stroke transform order. } TBLStrokeTransformOrder = ( { Transform after stroke => Transform(Stroke(Input)) [default]. } After = BL_STROKE_TRANSFORM_ORDER_AFTER, { Transform before stroke => Stroke(Transform(Input)). } Before = BL_STROKE_TRANSFORM_ORDER_BEFORE); type { Mode that specifies how curves are approximated to line segments. } TBLFlattenMode = ( { Use default mode (decided by Blend2D). } Default = BL_FLATTEN_MODE_DEFAULT, { Recursive subdivision flattening. } Recursive = BL_FLATTEN_MODE_RECURSIVE); type { Mode that specifies how to construct offset curves. } TBLOffsetMode = ( { Use default mode (decided by Blend2D). } Default = BL_OFFSET_MODE_DEFAULT, { Iterative offset construction. } Iterative = BL_OFFSET_MODE_ITERATIVE); type { TODO : Implement once added to Blend2D } TBLFitFlag = (_); TBLFitFlags = set of TBLFitFlag; { ============================================================================ [BLApproximationOptions] ============================================================================ } type { Options used to describe how geometry is approximated. This struct cannot be simply zeroed and then passed to functions that accept approximation options. Use BLApproximationOptions.Default to setup defaults and then alter values you want to change. } TBLApproximationOptions = record {$REGION 'Internal Declarations'} private class var FDefault: BLApproximationOptions; private FHandle: BLApproximationOptions; function GetFlattenMode: TBLFlattenMode; inline; function GetOffsetMode: TBLOffsetMode; inline; procedure SetFlattenMode(const AValue: TBLFlattenMode); inline; procedure SetOffsetMode(const AValue: TBLOffsetMode); inline; private class function GetDefault: TBLApproximationOptions; static; public class constructor Create; {$ENDREGION 'Internal Declarations'} public { Specifies how curves are flattened } property FlattenMode: TBLFlattenMode read GetFlattenMode write SetFlattenMode; { Specifies how curves are offsetted (used by stroking) } property OffsetMode: TBLOffsetMode read GetOffsetMode write SetOffsetMode; { Tolerance used to flatten curves. } property FlattenTolerance: Double read FHandle.flattenTolerance write FHandle.flattenTolerance; { Tolerance used to approximatecubic curves qith quadratic curves. } property SimplifyTolerance: Double read FHandle.simplifyTolerance write FHandle.simplifyTolerance; { Curve offsetting parameter, exact meaning depends on OffsetMode. } property OffsetParameter: Double read FHandle.offsetParameter write FHandle.offsetParameter; { Default approximation options } class property Default: TBLApproximationOptions read GetDefault; end; PBLApproximationOptions = ^TBLApproximationOptions; { ============================================================================ [BLStrokeOptions] ============================================================================ } type { Stroke options. } TBLStrokeOptions = record {$REGION 'Internal Declarations'} private type TScope = class(TInterfacedObject) private FHandle: PBLStrokeOptionsCore; public constructor Create(const AHandle: PBLStrokeOptionsCore); destructor Destroy; override; end; private FHandle: BLStrokeOptionsCore; FScope: IInterface; function GetStartCap: TBLStrokeCap; inline; procedure SetStartCap(const AValue: TBLStrokeCap); inline; function GetEndCap: TBLStrokeCap; inline; procedure SetEndCap(const AValue: TBLStrokeCap); inline; function GetJoin: TBLStrokeJoin; inline; procedure SetJoin(const AValue: TBLStrokeJoin); inline; function GetTransformOrder: TBLStrokeTransformOrder; inline; procedure SetTransformOrder(const AValue: TBLStrokeTransformOrder); inline; function GetDashArray: TArray; inline; procedure SetDashArray(const AValue: TArray); {$ENDREGION 'Internal Declarations'} public procedure Reset; procedure SetCaps(const ACap: TBLStrokeCap); overload; inline; procedure SetCaps(const AStartCap, AEndCap: TBLStrokeCap); overload; inline; property StartCap: TBLStrokeCap read GetStartCap write SetStartCap; property EndCap: TBLStrokeCap read GetEndCap write SetEndCap; property Join: TBLStrokeJoin read GetJoin write SetJoin; property TransformOrder: TBLStrokeTransformOrder read GetTransformOrder write SetTransformOrder; property Width: Double read FHandle.width write FHandle.width; property MiterLimit: Double read FHandle.miterLimit write FHandle.miterLimit; property DashOffset: Double read FHandle.dashOffset write FHandle.dashOffset; property DashArray: TArray read GetDashArray write SetDashArray; end; PBLStrokeOptions = ^TBLStrokeOptions; { ============================================================================ [BLPath - View] ============================================================================ } type { 2D path view provides pointers to vertex and command data along with their size. } TBLPathView = record {$REGION 'Internal Declarations'} private FHandle: BLPathView; function GetCommands: PBLPathCmd; inline; function GetVertices: PBLPoint; inline; function GetCount: Integer; inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; overload; inline; procedure Reset(const ACommands: PBLPathCmd; const AVertices: PBLPoint; const ACount: Integer); overload; inline; property Commands: PBLPathCmd read GetCommands; property Vertices: PBLPoint read GetVertices; property Count: Integer read GetCount; end; PBLPathView = ^TBLPathView; function BLPathView(const ACommands: PBLPathCmd; const AVertices: PBLPoint; const ACount: Integer): TBLPathView; inline; { ============================================================================ [BLPath] ============================================================================ } type { 2D vector path } IBLPath = interface ['{18B368F9-0E76-4C83-9B21-06CDB127430E}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetIsEmpty: Boolean; function GetCount: Integer; function GetCapacity: Integer; function GetVertexData: PBLPoint; function GetVertexDataEnd: PBLPoint; function GetLastVertex: TBLPoint; function GetCommandData: PBLPathCmd; function GetCommandDataEnd: PBLPathCmd; function GetView: TBLPathView; function GetInfoFlags: TBLPathFlags; function GetControlBox: TBLBox; function GetBoundingBox: TBLBox; function GetFigureRange(const AIndex: Integer): TBLRange; function GetHandle: PBLPathCore; {$ENDREGION 'Internal Declarations'} procedure Reset; function Clone: IBLPath; { Tests whether this path and the AOther path are equal. The equality check is deep. The data of both paths is examined and binary compared (thus a slight difference like -0 and +0 would make the equality check to fail). } function Equals(const AOther: IBLPath): Boolean; { Clears the content of the path. } procedure Clear; { Shrinks the capacity of the path to fit the current usage. } procedure Shrink; { Reserves the capacity of the path for at least ACoount vertices and commands. } procedure Reserve(const ACount: Integer); { Sets vertex at AIndex to ACmd and APt. Set APreserve to True to preserve the current command.} procedure SetVertexAt(const AIndex: Integer; const ACmd: TBLPathCmd; const APt: TBLPoint; const APreserve: Boolean = False); overload; { Sets vertex at AIndex to ACmd and [AX, AY]. Set APreserve to True to preserve the current command.} procedure SetVertexAt(const AIndex: Integer; const ACmd: TBLPathCmd; const AX, AY: Double; const APreserve: Boolean = False); overload; { Moves to AP0. Appends TBLPathCmd.Move[AP0] command to the path. } procedure MoveTo(const AP0: TBLPoint); overload; { Moves to [AX0, AY0]. Appends TBLPathCmd.Move[AX0, AY0] command to the path. } procedure MoveTo(const AX0, AY0: Double); overload; { Adds line to AP1. Appends TBLPathCmd.On[AP1] command to the path. } procedure LineTo(const AP1: TBLPoint); overload; { Adds line to [AX1, AY1]. Appends TBLPathCmd.On[AX1, AY1] command to the path. } procedure LineTo(const AX1, AY1: Double); overload; { Adds a polyline (LineTo) of the given APoly array. Appends multiple TBLPathCmd.On[X, Y] commands to the path depending. } procedure PolyTo(const APoly: TArray); overload; procedure PolyTo(const APoly: PBLPoint; const ACount: Integer); overload; { Adds a quadratic curve to AP1 and AP2. Appends the following commands to the path: * TBLPathCmd.Quad[AP1] * TBLPathCmd.On[AP2] Matches SVG 'Q' path command: https://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands } procedure QuadTo(const AP1, AP2: TBLPoint); overload; { Adds a quadratic curve to [AX1, AY1] and [AX2, AY2]. Appends the following commands to the path: * TBLPathCmd.Quad[AX1, AY1] * TBLPathCmd.On[AX2, AY2] Matches SVG 'Q' path command: https://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands } procedure QuadTo(const AX1, AY1, AX2, AY2: Double); overload; { Adds a cubic curve to AP1, AP2 and AP3. Appends the following commands to the path: * TBLPathCmd.Cubic[AP1] * TBLPathCmd.Cubic[AP2] * TBLPathCmd.On[AP3] Matches SVG 'C' path command: https://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands } procedure CubicTo(const AP1, AP2, AP3: TBLPoint); overload; { Adds a cubic curve to [AX1, AY1], [AX2, AY2] and [AX3, AY3]. Appends the following commands to the path: * TBLPathCmd.Cubic[AX1, AY1] * TBLPathCmd.Cubic[AX2, AY2] * TBLPathCmd.On[AX3, AY3] Matches SVG 'C' path command: https://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands } procedure CubicTo(const AX1, AY1, AX2, AY2, AX3, AY3: Double); overload; { Adds a smooth quadratic curve to AP2, calculating AP1 from last points. Appends the following commands to the path: * TBLPathCmd.Quad[calculated] * TBLPathCmd.On[AP2] Matches SVG 'T' path command: https://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands } procedure SmoothQuadTo(const AP2: TBLPoint); overload; { Adds a smooth quadratic curve to [AX2, AY2], calculating [AX1, AY1] from last points. Appends the following commands to the path: * TBLPathCmd.Quad[calculated] * TBLPathCmd.On[AX2, AY2] Matches SVG 'T' path command: https://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands } procedure SmoothQuadTo(const AX2, AY2: Double); overload; { Adds a smooth cubic curve to AP2 and AP3, calculating AP1 from last points. Appends the following commands to the path: * TBLPathCmd.Cubic[calculated] * TBLPathCmd.Cubic[AP2] * TBLPathCmd.On[AP3] Matches SVG 'S' path command: https://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands } procedure SmoothCubicTo(const AP2, AP3: TBLPoint); overload; { Adds a smooth cubic curve to [AX2, AY2] and [AX3, AY3], calculating [AX1, AY1] from last points. Appends the following commands to the path: * TBLPathCmd.Cubic[calculated] * TBLPathCmd.Cubic[[AX2, AY2]] * TBLPathCmd.On[[AX3, AY3]] Matches SVG 'S' path command: https://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands } procedure SmoothCubicTo(const AX2, AY2, AX3, AY3: Double); overload; { Adds an arc to the path. The center of the arc is specified by AC and radius by AR. Both AStart and ASweep angles are in radians. If the last vertex doesn't match the start of the arc then a LineTo would be emitted before adding the arc. Pass True in AForceMoveTo to always emit MoveTo at the beginning of the arc, which starts a new figure. } procedure ArcTo(const AC, AR: TBLPoint; const AStart, ASweep: Double; const AForceMoveTo: Boolean = False); overload; procedure ArcTo(const ACX, ACY, ARX, ARY, AStart, ASweep: Double; const AForceMoveTo: Boolean = False); overload; { Adds an arc quadrant (90deg) to the path. The first point AP1 specifies the quadrant corner and the last point AP2 specifies the end point. } procedure ArcQuadrantTo(const AP1, AP2: TBLPoint); overload; procedure ArcQuadrantTo(const AX1, AY1, AX2, AY2: Double); overload; { Adds an elliptic arc to the path that follows the SVG specification. Matches SVG 'A' path command: https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands } procedure EllipticArcTo(const ARP: TBLPoint; const AXAxisRotation: Double; const ALargeArcFlag, ASweepFlag: Boolean; const AP1: TBLPoint); overload; procedure EllipticArcTo(const ARX, ARY, AXAxisRotation: Double; const ALargeArcFlag, ASweepFlag: Boolean; const AX1, AY1: Double); overload; { Closes the current figure. Appends TBLPathCmd.Close to the path. Matches SVG 'Z' path command: https://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand } procedure Close; { Adds a closed rectangle to the path specified by ABox. } procedure AddBox(const ABox: TBLBoxI; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBox(const ABox: TBLBox; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a closed rectangle to the path specified by [AX0, AY0, AX1, AY1]. } procedure AddBox(const AX0, AY0, AX1, AY1: Double; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a closed rectangle to the path specified by ARect. } procedure AddRect(const ARect: TBLRectI; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRect(const ARect: TBLRect; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a closed rectangle to the path specified by [AX, AY, AW, AH]. } procedure AddRect(const AX, AY, AW, AH: Double; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a geometry to the path. } procedure AddGeometry(const AGeometryType: TBLGeometryType; const AGeometryData: Pointer; const AMatrix: PBLMatrix2D = nil; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); { Adds a closed circle to the path. } procedure AddCircle(const ACircle: TBLCircle; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddCircle(const ACircle: TBLCircle; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a closed ellipse to the path. } procedure AddEllipse(const AEllipse: TBLEllipse; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddEllipse(const AEllipse: TBLEllipse; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a closed rounded ractangle to the path. } procedure AddRoundRect(const ARoundRect: TBLRoundRect; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRoundRect(const ARoundRect: TBLRoundRect; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds an open arc to the path. } procedure AddArc(const AArc: TBLArc; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddArc(const AArc: TBLArc; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a closed chord to the path. } procedure AddChord(const AChord: TBLArc; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddChord(const AChord: TBLArc; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a closed pie to the path. } procedure AddPie(const APie: TBLArc; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPie(const APie: TBLArc; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds an open line to the path. } procedure AddLine(const ALine: TBLLine; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddLine(const ALine: TBLLine; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a closed triangle. } procedure AddTriangle(const ATriangle: TBLTriangle; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddTriangle(const ATriangle: TBLTriangle; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a polyline. } procedure AddPolyline(const APolyline: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: PBLPointI; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: PBLPointI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: PBLPoint; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: PBLPoint; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a polygon. } procedure AddPolygon(const APolygon: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: PBLPointI; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: PBLPointI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: PBLPoint; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: PBLPoint; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds an array of closed boxes. } procedure AddBoxArray(const ABoxes: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: PBLBoxI; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: PBLBoxI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: PBLBox; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: PBLBox; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds an array of closed rectangles. } procedure AddRectArray(const ARects: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: PBLRectI; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: PBLRectI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: PBLRect; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: PBLRect; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds a closed region (converted to set of rectangles). } procedure AddRegion(const ARegion: IBLRegion; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRegion(const ARegion: IBLRegion; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; { Adds other APath to this path. } procedure AddPath(const APath: IBLPath); overload; { Adds other APath sliced by the given ARange to this path. } procedure AddPath(const APath: IBLPath; const ARange: TBLRange); overload; { Adds other APath translated by ATranslate to this path. } procedure AddPath(const APath: IBLPath; const ATranslate: TBLPoint); overload; { Adds other APath translated by ATranslate and sliced by the given ARange to this path. } procedure AddPath(const APath: IBLPath; const ARange: TBLRange; const ATranslate: TBLPoint); overload; { Adds other APath transformed by AMatrix to this path. } procedure AddPath(const APath: IBLPath; const AMatrix: TBLMatrix2D); overload; { Adds other APath transformed by AMatrix and sliced by the given ARange to this path. } procedure AddPath(const APath: IBLPath; const ARange: TBLRange; const AMatrix: TBLMatrix2D); overload; { Adds other APath, but reversed. } procedure AddReversedPath(const APath: IBLPath; const AReverseMode: TBLPathReverseMode); overload; procedure AddReversedPath(const APath: IBLPath; const ARange: TBLRange; const AReverseMode: TBLPathReverseMode); overload; { Adds a stroke of APath to this path. } procedure AddStrokedPath(const APath: IBLPath; const AStrokeOptions: TBLStrokeOptions; const AApproximationOptions: TBLApproximationOptions); overload; procedure AddStrokedPath(const APath: IBLPath; const ARange: TBLRange; const AStrokeOptions: TBLStrokeOptions; const AApproximationOptions: TBLApproximationOptions); overload; { Manipulation } procedure RemoveRange(const ARange: TBLRange); { Translates the whole path by AP. } procedure Translate(const AP: TBLPoint); overload; { Translates a part of the path specified by the given ARange by AP. } procedure Translate(const ARange: TBLRange; const AP: TBLPoint); overload; { Transforms the whole path by AMatrix. } procedure Transform(const AMatrix: TBLMatrix2D); overload; { Transforms a part of the path specified by the given ARange by AMatrix. } procedure Transform(const ARange: TBLRange; const AMatrix: TBLMatrix2D); overload; { Fits the whole path into the given ARect by taking into account fit flags passed by AFitFlags. } procedure FitTo(const ARect: TBLRect; const AFitFlags: TBLFitFlags = []); overload; { Fits a part of the path specified by the given ARange into the given ARect by taking into account fit flags passed by AFitFlags. } procedure FitTo(const ARange: TBLRange; const ARect: TBLRect; const AFitFlags: TBLFitFlags = []); overload; function GetClosestVertex(const AP: TBLPoint; const AMaxDistance: Double): Integer; overload; function GetClosestVertex(const AP: TBLPoint; const AMaxDistance: Double; out AActualDistance: Double): Integer; overload; { Hit tests the given point AP by respecting the given AFillRule. } function HitTest(const AP: TBLPoint; const AFillRule: TBLFillRule): TBLHitTest; { Tests whether the 2D path is a built-in nil instance. } property IsNone: Boolean read GetIsNone; { Tests whether the 2D path is empty (its size equals zero). } property IsEmpty: Boolean read GetIsEmpty; { Count of vertices used } property Count: Integer read GetCount; { Path capacity (count of allocated vertices) } property Capacity: Integer read GetCapacity; { Path's vertex data (read-only). } property VertexData: PBLPoint read GetVertexData; { End of path's vertex data (read-only). } property VertexDataEnd: PBLPoint read GetVertexDataEnd; { The last vertex of the path. If the very last command of the path is TBLPathCmd.Close then the path will be iterated in reverse order to match the initial vertex of the last figure. } property LastVertex: TBLPoint read GetLastVertex; { Path's command data (read-only). } property CommandData: PBLPathCmd read GetCommandData; { End of path's command data (read-only). } property CommandDataEnd: PBLPathCmd read GetCommandDataEnd; { The path data as a read-only TBLPathView. } property View: TBLPathView read GetView; { Update a path information if necessary. } property InfoFlags: TBLPathFlags read GetInfoFlags; { The bounding box of all vertices and control points. Control box is simply bounds of all vertices the path has without further processing. It contains both on-path and off-path points. Consider using BoundingBox if you need a visual bounding box. } property ControlBox: TBLBox read GetControlBox; { The bounding box of all on-path vertices and curve extremas. The bounding box could be smaller than a bounding box obtained by ControlBox as it's calculated by merging only start/end points and curves at their extremas (not control points). The resulting bounding box represents a visual bounds of the path. } property BoundingBox: TBLBox read GetBoundingBox; { The range describing figures at the given AIndex. } property FigureRanges[const AIndex: Integer]: TBLRange read GetFigureRange; { Internal handle for use with the C API } property Handle: PBLPathCore read GetHandle; end; type { Optional callback that can be used to consume a path data. } TBLPathSinkEvent = function(const APath: IBLPath; const AInfo: Pointer): TBLResultCode of object; type { Implements IBLPath } TBLPath = class(TInterfacedObject, IBLPath) {$REGION 'Internal Declarations'} private FHandle: BLPathCore; protected { IBLPath } function GetIsNone: Boolean; function GetIsEmpty: Boolean; function GetCount: Integer; function GetCapacity: Integer; function GetVertexData: PBLPoint; function GetVertexDataEnd: PBLPoint; function GetLastVertex: TBLPoint; function GetCommandData: PBLPathCmd; function GetCommandDataEnd: PBLPathCmd; function GetView: TBLPathView; function GetInfoFlags: TBLPathFlags; function GetControlBox: TBLBox; function GetBoundingBox: TBLBox; function GetFigureRange(const AIndex: Integer): TBLRange; function GetHandle: PBLPathCore; procedure Reset; function Clone: IBLPath; function Equals(const AOther: IBLPath): Boolean; reintroduce; overload; procedure Clear; procedure Shrink; procedure Reserve(const ACount: Integer); procedure SetVertexAt(const AIndex: Integer; const ACmd: TBLPathCmd; const APt: TBLPoint; const APreserve: Boolean = False); overload; procedure SetVertexAt(const AIndex: Integer; const ACmd: TBLPathCmd; const AX, AY: Double; const APreserve: Boolean = False); overload; procedure MoveTo(const AP0: TBLPoint); overload; procedure MoveTo(const AX0, AY0: Double); overload; procedure LineTo(const AP1: TBLPoint); overload; procedure LineTo(const AX1, AY1: Double); overload; procedure PolyTo(const APoly: TArray); overload; procedure PolyTo(const APoly: PBLPoint; const ACount: Integer); overload; procedure QuadTo(const AP1, AP2: TBLPoint); overload; procedure QuadTo(const AX1, AY1, AX2, AY2: Double); overload; procedure CubicTo(const AP1, AP2, AP3: TBLPoint); overload; procedure CubicTo(const AX1, AY1, AX2, AY2, AX3, AY3: Double); overload; procedure SmoothQuadTo(const AP2: TBLPoint); overload; procedure SmoothQuadTo(const AX2, AY2: Double); overload; procedure SmoothCubicTo(const AP2, AP3: TBLPoint); overload; procedure SmoothCubicTo(const AX2, AY2, AX3, AY3: Double); overload; procedure ArcTo(const AC, AR: TBLPoint; const AStart, ASweep: Double; const AForceMoveTo: Boolean = False); overload; procedure ArcTo(const ACX, ACY, ARX, ARY, AStart, ASweep: Double; const AForceMoveTo: Boolean = False); overload; procedure ArcQuadrantTo(const AP1, AP2: TBLPoint); overload; procedure ArcQuadrantTo(const AX1, AY1, AX2, AY2: Double); overload; procedure EllipticArcTo(const ARP: TBLPoint; const AXAxisRotation: Double; const ALargeArcFlag, ASweepFlag: Boolean; const AP1: TBLPoint); overload; procedure EllipticArcTo(const ARX, ARY, AXAxisRotation: Double; const ALargeArcFlag, ASweepFlag: Boolean; const AX1, AY1: Double); overload; procedure Close; procedure AddBox(const ABox: TBLBoxI; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBox(const ABox: TBLBox; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBox(const AX0, AY0, AX1, AY1: Double; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRect(const ARect: TBLRectI; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRect(const ARect: TBLRect; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRect(const AX, AY, AW, AH: Double; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddGeometry(const AGeometryType: TBLGeometryType; const AGeometryData: Pointer; const AMatrix: PBLMatrix2D = nil; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); procedure AddCircle(const ACircle: TBLCircle; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddCircle(const ACircle: TBLCircle; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddEllipse(const AEllipse: TBLEllipse; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddEllipse(const AEllipse: TBLEllipse; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRoundRect(const ARoundRect: TBLRoundRect; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRoundRect(const ARoundRect: TBLRoundRect; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddArc(const AArc: TBLArc; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddArc(const AArc: TBLArc; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddChord(const AChord: TBLArc; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddChord(const AChord: TBLArc; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPie(const APie: TBLArc; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPie(const APie: TBLArc; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddLine(const ALine: TBLLine; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddLine(const ALine: TBLLine; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddTriangle(const ATriangle: TBLTriangle; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddTriangle(const ATriangle: TBLTriangle; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: PBLPointI; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: PBLPointI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: PBLPoint; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolyline(const APolyline: PBLPoint; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: PBLPointI; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: PBLPointI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: PBLPoint; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPolygon(const APolygon: PBLPoint; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: PBLBoxI; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: PBLBoxI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: PBLBox; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddBoxArray(const ABoxes: PBLBox; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: PBLRectI; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: PBLRectI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: TBLArrayView; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: PBLRect; const ACount: Integer; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRectArray(const ARects: PBLRect; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRegion(const ARegion: IBLRegion; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddRegion(const ARegion: IBLRegion; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection = TBLGeometryDirection.CW); overload; procedure AddPath(const APath: IBLPath); overload; procedure AddPath(const APath: IBLPath; const ARange: TBLRange); overload; procedure AddPath(const APath: IBLPath; const ATranslate: TBLPoint); overload; procedure AddPath(const APath: IBLPath; const ARange: TBLRange; const ATranslate: TBLPoint); overload; procedure AddPath(const APath: IBLPath; const AMatrix: TBLMatrix2D); overload; procedure AddPath(const APath: IBLPath; const ARange: TBLRange; const AMatrix: TBLMatrix2D); overload; procedure AddReversedPath(const APath: IBLPath; const AReverseMode: TBLPathReverseMode); overload; procedure AddReversedPath(const APath: IBLPath; const ARange: TBLRange; const AReverseMode: TBLPathReverseMode); overload; procedure AddStrokedPath(const APath: IBLPath; const AStrokeOptions: TBLStrokeOptions; const AApproximationOptions: TBLApproximationOptions); overload; procedure AddStrokedPath(const APath: IBLPath; const ARange: TBLRange; const AStrokeOptions: TBLStrokeOptions; const AApproximationOptions: TBLApproximationOptions); overload; procedure RemoveRange(const ARange: TBLRange); procedure Translate(const AP: TBLPoint); overload; procedure Translate(const ARange: TBLRange; const AP: TBLPoint); overload; procedure Transform(const AMatrix: TBLMatrix2D); overload; procedure Transform(const ARange: TBLRange; const AMatrix: TBLMatrix2D); overload; procedure FitTo(const ARect: TBLRect; const AFitFlags: TBLFitFlags = []); overload; procedure FitTo(const ARange: TBLRange; const ARect: TBLRect; const AFitFlags: TBLFitFlags = []); overload; function GetClosestVertex(const AP: TBLPoint; const AMaxDistance: Double): Integer; overload; function GetClosestVertex(const AP: TBLPoint; const AMaxDistance: Double; out AActualDistance: Double): Integer; overload; function HitTest(const AP: TBLPoint; const AFillRule: TBLFillRule): TBLHitTest; {$ENDREGION 'Internal Declarations'} public constructor Create; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; {$ENDREGION 'Path'} {$REGION 'Format'} { ============================================================================ [Enums] ============================================================================ } type { Pixel format. Compatibility Table ------------------- +---------------------+---------------------+-----------------------------+ | Blend2D Format | Cairo Format | QImage::Format | +---------------------+---------------------+-----------------------------+ | BL_FORMAT_PRGB32 | CAIRO_FORMAT_ARGB32 | Format_ARGB32_Premultiplied | | BL_FORMAT_XRGB32 | CAIRO_FORMAT_RGB24 | Format_RGB32 | | BL_FORMAT_A8 | CAIRO_FORMAT_A8 | n/a | +---------------------+---------------------+-----------------------------+ } TBLFormat = ( { None or invalid pixel format. } None = BL_FORMAT_NONE, { 32-bit premultiplied ARGB pixel format (8-bit components). } PRGB32 = BL_FORMAT_PRGB32, { 32-bit (X)RGB pixel format (8-bit components, alpha ignored). } XRGB32 = BL_FORMAT_XRGB32, { 8-bit alpha-only pixel format. } A8 = BL_FORMAT_A8); type { Pixel format flags. } TBLFormatFlag = ( { Pixel format provides RGB components. } RGB = 0, { Pixel format provides only alpha component. } Alpha = 1, { Pixel format provides LUM component (and not RGB components). } LUM = 2, { Indexed pixel format the requres a palette (I/O only). } Indexed = 4, { RGB components are premultiplied by alpha component. } Premultiplied = 8, { Pixel format doesn't use native byte-order (I/O only). } ByteSwap = 9, { The following flags are only informative. They are part of BLFormatInfo, but doesn't have to be passed to IBLPixelConverter as they can be easily calculated. } { Pixel components are byte aligned (all 8bpp). } ByteAligned = 16, { Pixel has some undefined bits that represent no information. For example a 32-bit XRGB pixel has 8 undefined bits that are usually set to all ones so the format can be interpreted as premultiplied RGB as well. There are other formats like 16_0555 where the bit has no information and is usually set to zero. Blend2D doesn't rely on the content of such bits. } UndefinedBits = 17, { Little-endian format. Note: This is not a real flag that you can test, it's only provided for convenience to define little endian pixel formats. } LittleEndian = 0, { Big-endian format. Note: This is not a real flag that you can test, it's only provided for convenience to define little endian pixel formats. } BigEndian = ByteSwap); TBLFormatFlags = set of TBLFormatFlag; type _TBLFormatFlagsHelper = record helper for TBLFormatFlags public const { Pixel format provides RGB and Alpha components. } RGBA = [TBLFormatFlag.RGB, TBLFormatFlag.Alpha]; { Pixel format provides LUM and Alpha components (and not RGB components). } LUMA = [TBLFormatFlag.LUM, TBLFormatFlag.Alpha]; end; { ============================================================================ [BLFormatInfo] ============================================================================ } type { Provides a detailed information about a pixel format. Use the TBLFormat.Info property to get information of Blend2D native pixel formats. } TBLFormatInfo = record {$REGION 'Internal Declarations'} private FHandle: BLFormatInfo; function GetFlags: TBLFormatFlags; inline; procedure SetFlags(const AValue: TBLFormatFlags); inline; function GetPalette: PBLRgba32; inline; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLFormatInfo): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLFormatInfo): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const ADepth: Integer; const AFlags: TBLFormatFlags; const ARSize, AGSize, ABSize, AASize, ARShift, AGShift, ABShift, AAShift: Byte); overload; inline; procedure SetSizes(const ARSize, AGSize, ABSize, AASize: Byte); inline; procedure SetShifts(const ARShift, AGShift, ABShift, AAShift: Byte); inline; { Query Blend2D AFormat and copy it to this format info. Raises TBLResultCode.InvalidValue if the format is invalid (and resets this record in that case). Note: TBLFormat.None is considered an invalid format, thus if it's passed to Query, a TBLResultCode.InvalidValue error is raised. } procedure Query(const AFormat: TBLFormat); { Sanitize this record. Sanitizer verifies whether the format is valid and updates the format information about flags to values that Blend2D expects. For example format flags are properly examined and simplified if possible, byte-swap is implicitly performed for formats where a single component matches one byte, etc... } procedure Sanitize; property Depth: Integer read FHandle.depth write FHandle.depth; property Flags: TBLFormatFlags read GetFlags write SetFlags; property RedSize: Byte read FHandle.rSize write FHandle.rSize; property GreenSize: Byte read FHandle.gSize write FHandle.gSize; property BlueSize: Byte read FHandle.bSize write FHandle.bSize; property AlphaSize: Byte read FHandle.aSize write FHandle.aSize; property RedShift: Byte read FHandle.rShift write FHandle.rShift; property GreenShift: Byte read FHandle.gShift write FHandle.gShift; property BlueShift: Byte read FHandle.bShift write FHandle.bShift; property AlphaShift: Byte read FHandle.aShift write FHandle.aShift; property Palette: PBLRgba32 read GetPalette; end; PBLFormatInfo = ^TBLFormatInfo; type { Additional information about pixel formats } _TBLFormatHelper = record helper for TBLFormat {$REGION 'Internal Declarations'} private function GetInfo: TBLFormatInfo; {$ENDREGION 'Internal Declarations'} public { Information about this pixel format } property Info: TBLFormatInfo read GetInfo; end; {$ENDREGION 'Format'} {$REGION 'Image'} { ============================================================================ [BLImage - Enums] ============================================================================ } type { Flags used by TBLImageInfo. } TBLImageInfoFlag = ( { Progressive mode. } Progressive = 0); TBLImageInfoFlags = set of TBLImageInfoFlag; { ============================================================================ [BLImage - Info] ============================================================================ } type { Image information provided by image codecs. } TBLImageInfo = record {$REGION 'Internal Declarations'} private FHandle: BLImageInfo; function GetCompression: String; inline; function GetDensity: TBLSize; inline; function GetDepth: Integer; inline; function GetFlags: TBLFormatFlags; inline; function GetFormat: String; inline; function GetFrameCount: Integer; inline; function GetPlaneCount: Integer; inline; function GetSize: TBLSizeI; inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; { Image size. } property Size: TBLSizeI read GetSize; { Pixel density per one meter, can contain fractions. } property Density: TBLSize read GetDensity; { Image flags. } property Flags: TBLFormatFlags read GetFlags; { Image depth. } property Depth: Integer read GetDepth; { Number of planes. } property PlaneCount: Integer read GetPlaneCount; { Number of frames (0 = unknown/unspecified). } property FrameCount: Integer read GetFrameCount; { Image format (as understood by codec). } property Format: String read GetFormat; { Image compression (as understood by codec). } property Compression: String read GetCompression; end; PBLImageInfo = ^TBLImageInfo; { ============================================================================ [BLImage - Enums] ============================================================================ } type { Filter type used by IBLImage.Scale. } TBLImageScaleFilter = ( { No filter or uninitialized. } None = BL_IMAGE_SCALE_FILTER_NONE, { Nearest neighbor filter (radius 1.0). } Nearest = BL_IMAGE_SCALE_FILTER_NEAREST, { Bilinear filter (radius 1.0). } Bilinear = BL_IMAGE_SCALE_FILTER_BILINEAR, { Bicubic filter (radius 2.0). } Bicubic = BL_IMAGE_SCALE_FILTER_BICUBIC, { Bell filter (radius 1.5). } Bell = BL_IMAGE_SCALE_FILTER_BELL, { Gauss filter (radius 2.0). } Gauss = BL_IMAGE_SCALE_FILTER_GAUSS, { Hermite filter (radius 1.0). } Hermite = BL_IMAGE_SCALE_FILTER_HERMITE, { Hanning filter (radius 1.0). } Hanning = BL_IMAGE_SCALE_FILTER_HANNING, { Catrom filter (radius 2.0). } Catrom = BL_IMAGE_SCALE_FILTER_CATROM, { Bessel filter (radius 3.2383). } Bessel = BL_IMAGE_SCALE_FILTER_BESSEL, { Sinc filter (radius 2.0, adjustable through TLImageScaleOptions). } Sinc = BL_IMAGE_SCALE_FILTER_SINC, { Lanczos filter (radius 2.0, adjustable through TBLImageScaleOptions). } Lanczos = BL_IMAGE_SCALE_FILTER_LANCZOS, { Blackman filter (radius 2.0, adjustable through TBLImageScaleOptions). } Blackman = BL_IMAGE_SCALE_FILTER_BLACKMAN, { Mitchell filter (radius 2.0, parameters 'b' and 'c' passed through TBLImageScaleOptions). } Mitchell = BL_IMAGE_SCALE_FILTER_MITCHELL, { Filter using a user-function, must be passed through TBLImageScaleOptions. } User = BL_IMAGE_SCALE_FILTER_USER); { ============================================================================ [BLImage - Typedefs] ============================================================================ } type { A user function that can be used by IBLImage.Scale. } TBLImageScaleUserFunc = function(const ADst, AArray: PDouble; const ACount: NativeInt; const AData: Pointer): Integer; cdecl; { ============================================================================ [BLImage - Data] ============================================================================ } type { Data that describes a raster image. Used by IBLImage. } TBLImageData = record {$REGION 'Internal Declarations'} private FHandle: BLImageData; function GetFlags: TBLFormatFlags; inline; function GetFormat: TBLFormat; inline; function GetSize: TBLSizeI; inline; procedure SetFlags(const AValue: TBLFormatFlags); inline; procedure SetFormat(const AValue: TBLFormat); inline; procedure SetSize(const AValue: TBLSizeI); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; property PixelData: Pointer read FHandle.pixelData write FHandle.pixelData; property Stride: NativeInt read FHandle.stride write FHandle.stride; property Size: TBLSizeI read GetSize write SetSize; property Format: TBLFormat read GetFormat write SetFormat; property Flags: TBLFormatFlags read GetFlags write SetFlags; end; PBLImageData = ^TBLImageData; { ============================================================================ [BLImage - ScaleOptions] ============================================================================ } type { Options that can used to customize image scaling. } TBLImageScaleOptions = record {$REGION 'Internal Declarations'} private FHandle: BLImageScaleOptions; function GetUserFunc: TBLImageScaleUserFunc; inline; procedure SetUserFunc(const AValue: TBLImageScaleUserFunc); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; procedure ResetToDefaults; inline; property UserFunc: TBLImageScaleUserFunc read GetUserFunc write SetUserFunc; property UserData: Pointer read FHandle.userData write FHandle.userData; property Radius: Double read FHandle.radius write FHandle.radius; property MitchellB: Double read FHandle.mitchell.b write FHandle.mitchell.b; property MitchellC: Double read FHandle.mitchell.c write FHandle.mitchell.c; end; PBLImageScaleOptions = ^TBLImageScaleOptions; type IBLImage = interface; IBLImageCodec = interface; { This event is called when IBLImage.InitializeFromData is used and the image is destroyed. } TBLImageDestroyEvent = procedure (const AImage: IBLImage) of object; { 2D raster image } IBLImage = interface ['{9E756ED1-76AB-4318-92BD-F6D7F14447A5}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetIsEmpty: Boolean; function GetWidth: Integer; function GetHeight: Integer; function GetSize: TBLSizeI; function GetFormat: TBLFormat; function GetHandle: PBLImageCore; {$ENDREGION 'Internal Declarations'} { Initializes a new image of a specified width, height, and format. } procedure Initialize(const AWidth, AHeight: Integer; const AFormat: TBLFormat = TBLFormat.PRGB32); { Initializes a new image from external data. The pixel data is *not* copied and must stay alive as long as the image is alive. Use AOnDestroy to get notified when the image is destroyed and you can safely free the pixel data. } procedure InitializeFromData(const AWidth, AHeight: Integer; const AFormat: TBLFormat; const APixelData: Pointer; const AStride: Integer; const AOnDestroy: TBLImageDestroyEvent = nil); procedure Reset; function Clone: IBLImage; function Equals(const AOther: IBLImage): Boolean; procedure GetData(out AData: TBLImageData); procedure MakeMutable; overload; procedure MakeMutable(out AData: TBLImageData); overload; procedure Convert(const AFormat: TBLFormat); procedure ScaleTo(const ADest: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter); overload; procedure ScaleTo(const ADest: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter; const AOptions: TBLImageScaleOptions); overload; procedure ReadFromFile(const AFilename: String); overload; procedure ReadFromFile(const AFilename: String; const ACodecs: TArray); overload; procedure ReadFromData(const AData: Pointer; const ASize: Integer); overload; procedure ReadFromData(const AData: Pointer; const ASize: Integer; const ACodecs: TArray); overload; procedure ReadFromData(const AData: TBytes); overload; procedure ReadFromData(const AData: TBytes; const ACodecs: TArray); overload; procedure ReadFromData(const AView: TBLArrayView); overload; procedure ReadFromData(const AView: TBLArrayView; const ACodecs: TArray); overload; procedure WriteToFile(const AFilename: String); overload; procedure WriteToFile(const AFilename: String; const ACodec: IBLImageCodec); overload; function WriteToData(const ACodec: IBLImageCodec): TBytes; { Tests whether the image is a built-in nil instance. } property IsNone: Boolean read GetIsNone; { Tests whether the image is empty (has no size). } property IsEmpty: Boolean read GetIsEmpty; { Image width. } property Width: Integer read GetWidth; { Image height. } property Height: Integer read GetHeight; { Image size. } property Size: TBLSizeI read GetSize; { Image format. } property Format: TBLFormat read GetFormat; { Internal handle for use with the C API } property Handle: PBLImageCore read GetHandle; end; { Implements IBLImage } TBLImage = class(TInterfacedObject, IBLImage) {$REGION 'Internal Declarations'} private type TDestroyData = record Image: IBLImage; Event: TBLImageDestroyEvent; end; PDestroyData = ^TDestroyData; private FHandle: BLImageCore; FIsReference: Boolean; private class procedure DoDestroy(impl, destroyData: Pointer); cdecl; static; protected { IBLImage } function GetIsNone: Boolean; function GetIsEmpty: Boolean; function GetWidth: Integer; function GetHeight: Integer; function GetSize: TBLSizeI; function GetFormat: TBLFormat; function GetHandle: PBLImageCore; procedure Initialize(const AWidth, AHeight: Integer; const AFormat: TBLFormat); procedure InitializeFromData(const AWidth, AHeight: Integer; const AFormat: TBLFormat; const APixelData: Pointer; const AStride: Integer; const AOnDestroy: TBLImageDestroyEvent); procedure Reset; function Clone: IBLImage; function Equals(const AOther: IBLImage): Boolean; reintroduce; overload; procedure GetData(out AData: TBLImageData); procedure MakeMutable; overload; procedure MakeMutable(out AData: TBLImageData); overload; procedure Convert(const AFormat: TBLFormat); procedure ScaleTo(const ADest: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter); overload; procedure ScaleTo(const ADest: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter; const AOptions: TBLImageScaleOptions); overload; procedure ReadFromFile(const AFilename: String); overload; procedure ReadFromFile(const AFilename: String; const ACodecs: TArray); overload; procedure ReadFromData(const AData: Pointer; const ASize: Integer); overload; procedure ReadFromData(const AData: Pointer; const ASize: Integer; const ACodecs: TArray); overload; procedure ReadFromData(const AData: TBytes); overload; procedure ReadFromData(const AData: TBytes; const ACodecs: TArray); overload; procedure ReadFromData(const AView: TBLArrayView); overload; procedure ReadFromData(const AView: TBLArrayView; const ACodecs: TArray); overload; procedure WriteToFile(const AFilename: String); overload; procedure WriteToFile(const AFilename: String; const ACodec: IBLImageCodec); overload; function WriteToData(const ACodec: IBLImageCodec): TBytes; private constructor Create(const AHandle: BLImageCore; const AIsReference: Boolean); overload; {$ENDREGION 'Internal Declarations'} public constructor Create; overload; constructor Create(const AWidth, AHeight: Integer; const AFormat: TBLFormat = TBLFormat.PRGB32); overload; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; class procedure Scale(const ASrc, ADst: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter); overload; static; class procedure Scale(const ASrc, ADst: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter; const AOptions: TBLImageScaleOptions); overload; static; end; {$ENDREGION 'Image'} {$REGION 'Image Codec'} { ============================================================================ [BLImageCodec - Enums] ============================================================================ } { Image codec feature bits. } TBLImageCodecFeature = ( { Image codec supports reading images (can create IBLImageDecoder). } Read = 0, { Image codec supports writing images (can create IBLImageEncoder). } Write = 1, { Image codec supports lossless compression. } Lossless = 2, { Image codec supports lossy compression. } Lossy = 3, { Image codec supports writing multiple frames (GIF). } MultiFrame = 4, { Image codec supports IPTC metadata. } IPTC = 28, { Image codec supports EXIF metadata. } EXIF = 29, { Image codec supports XMP metadata. } XMP = 30); TBLImageCodecFeatures = set of TBLImageCodecFeature; { ============================================================================ [BLImageDecoder] ============================================================================ } { Image decoder } IBLImageDecoder = interface ['{D68437C2-E6EF-46F1-9191-28F844EF17C6}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetLastResult: TBLResultCode; function GetFrameIndex: Integer; function GetBufferIndex: NativeInt; function GetHandle: PBLImageDecoderCore; {$ENDREGION 'Internal Declarations'} procedure Reset; function Equals(const AOther: IBLImageDecoder): Boolean; procedure Restart; procedure ReadInfo(const ABuffer: TBytes; out AInfo: TBLImageInfo); overload; procedure ReadInfo(const ABuffer: TBLArrayView; out AInfo: TBLImageInfo); overload; procedure ReadInfo(const ABuffer: Pointer; const ASize: Integer; out AInfo: TBLImageInfo); overload; function ReadFrame(const ABuffer: TBytes): IBLImage; overload; function ReadFrame(const ABuffer: TBLArrayView): IBLImage; overload; function ReadFrame(const ABuffer: Pointer; const ASize: Integer): IBLImage; overload; { Tests whether the image decoder is a built-in nil instance. } property IsNone: Boolean read GetIsNone; { Last decoding result. } property LastResult: TBLResultCode read GetLastResult; { Current frame index (to be decoded). } property FrameIndex: Integer read GetFrameIndex; { Position in source buffer. } property BufferIndex: NativeInt read GetBufferIndex; { Internal handle for use with the C API } property Handle: PBLImageDecoderCore read GetHandle; end; { Implements IBLImageDecoder } TBLImageDecoder = class(TInterfacedObject, IBLImageDecoder) {$REGION 'Internal Declarations'} private FHandle: BLImageDecoderCore; protected { IBLImageDecoder } function GetIsNone: Boolean; function GetLastResult: TBLResultCode; function GetFrameIndex: Integer; function GetBufferIndex: NativeInt; function GetHandle: PBLImageDecoderCore; procedure Reset; function Equals(const AOther: IBLImageDecoder): Boolean; reintroduce; overload; procedure Restart; procedure ReadInfo(const ABuffer: TBytes; out AInfo: TBLImageInfo); overload; procedure ReadInfo(const ABuffer: TBLArrayView; out AInfo: TBLImageInfo); overload; procedure ReadInfo(const ABuffer: Pointer; const ASize: Integer; out AInfo: TBLImageInfo); overload; function ReadFrame(const ABuffer: TBytes): IBLImage; overload; function ReadFrame(const ABuffer: TBLArrayView): IBLImage; overload; function ReadFrame(const ABuffer: Pointer; const ASize: Integer): IBLImage; overload; {$ENDREGION 'Internal Declarations'} public constructor Create; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; { ============================================================================ [BLImageEncoder] ============================================================================ } { Image encoder } IBLImageEncoder = interface ['{D754FC7A-AC83-4543-8200-AE896920FFB0}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetLastResult: TBLResultCode; function GetFrameIndex: Integer; function GetBufferIndex: NativeInt; function GetHandle: PBLImageEncoderCore; {$ENDREGION 'Internal Declarations'} procedure Reset; function Equals(const AOther: IBLImageEncoder): Boolean; procedure Restart; { Encodes the given AImage and returns the encoded data. } function WriteFrame(const AImage: IBLImage): TBytes; { Tests whether the image encoder is a built-in nil instance. } property IsNone: Boolean read GetIsNone; { Last encoding result. } property LastResult: TBLResultCode read GetLastResult; { Current frame index (yet to be written). } property FrameIndex: Integer read GetFrameIndex; { Position in destination buffer. } property BufferIndex: NativeInt read GetBufferIndex; { Internal handle for use with the C API } property Handle: PBLImageEncoderCore read GetHandle; end; { Implements IBLImageEncoder } TBLImageEncoder = class(TInterfacedObject, IBLImageEncoder) {$REGION 'Internal Declarations'} private FHandle: BLImageEncoderCore; protected { IBLImageEncoder } function GetIsNone: Boolean; function GetLastResult: TBLResultCode; function GetFrameIndex: Integer; function GetBufferIndex: NativeInt; function GetHandle: PBLImageEncoderCore; procedure Reset; function Equals(const AOther: IBLImageEncoder): Boolean; reintroduce; overload; procedure Restart; function WriteFrame(const AImage: IBLImage): TBytes; {$ENDREGION 'Internal Declarations'} public constructor Create; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; { ============================================================================ [BLImageCodec] ============================================================================ } { Image codec. Provides a unified interface for inspecting image data and creating image decoders & encoders. } IBLImageCodec = interface ['{5F2E0C15-3CF5-4454-ADA4-CEE5D4A3B542}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetName: String; function GetVendor: String; function GetMimeType: String; function GetExtensions: String; function GetFeatures: TBLImageCodecFeatures; function GetHandle: PBLImageCodecCore; {$ENDREGION 'Internal Declarations'} procedure Reset; function Equals(const AOther: IBLImageCodec): Boolean; { Tests whether the image codec has a given feature. } function HasFeature(const AFeature: TBLImageCodecFeature): Boolean; function FindByName(const AName: String): Boolean; overload; function FindByName(const AName: String; const ACodecs: TArray): Boolean; overload; function FindByExtension(const AExt: String): Boolean; overload; function FindByExtension(const AExt: String; const ACodecs: TArray): Boolean; overload; function FindByData(const AData: Pointer; const ASize: Integer): Boolean; overload; function FindByData(const AData: Pointer; const ASize: Integer; const ACodecs: TArray): Boolean; overload; function FindByData(const AData: TBytes): Boolean; overload; function FindByData(const AData: TBytes; const ACodecs: TArray): Boolean; overload; { Returns a score } function InspectData(const ABuffer: TBytes): Cardinal; overload; function InspectData(const ABuffer: TBLArrayView): Cardinal; overload; function InspectData(const ABuffer: Pointer; const ASize: Integer): Cardinal; overload; { Tests whether the image codec is a built-in nil instance. } property IsNone: Boolean read GetIsNone; { Image codec name (i.e, "PNG", "JPEG", etc...). } property Name: String read GetName; { The image codec vendor (i.e. "Blend2D" for all built-in codecs). } property Vendor: String read GetVendor; { Mime-type associated with the image codec's format. } property MimeType: String read GetMimeType; { A list of file extensions used to store image of this codec, separated by '|' character. } property Extensions: String read GetExtensions; { Image codec features } property Features: TBLImageCodecFeatures read GetFeatures; { Internal handle for use with the C API } property Handle: PBLImageCodecCore read GetHandle; end; type { Implements IBLImageCodec } TBLImageCodec = class(TInterfacedObject, IBLImageCodec) {$REGION 'Internal Declarations'} private FHandle: BLImageCodecCore; FIsReference: Boolean; private class function GetBuiltInCodecs: TArray; static; protected { IBLImageCodec } function GetIsNone: Boolean; function GetName: String; function GetVendor: String; function GetMimeType: String; function GetExtensions: String; function GetFeatures: TBLImageCodecFeatures; function GetHandle: PBLImageCodecCore; procedure Reset; function Equals(const AOther: IBLImageCodec): Boolean; reintroduce; overload; function HasFeature(const AFeature: TBLImageCodecFeature): Boolean; function FindByName(const AName: String): Boolean; overload; function FindByName(const AName: String; const ACodecs: TArray): Boolean; overload; function FindByExtension(const AExt: String): Boolean; overload; function FindByExtension(const AExt: String; const ACodecs: TArray): Boolean; overload; function FindByData(const AData: Pointer; const ASize: Integer): Boolean; overload; function FindByData(const AData: Pointer; const ASize: Integer; const ACodecs: TArray): Boolean; overload; function FindByData(const AData: TBytes): Boolean; overload; function FindByData(const AData: TBytes; const ACodecs: TArray): Boolean; overload; function InspectData(const ABuffer: TBytes): Cardinal; overload; function InspectData(const ABuffer: TBLArrayView): Cardinal; overload; function InspectData(const ABuffer: Pointer; const ASize: Integer): Cardinal; overload; protected constructor Create(const AHandle: BLImageCodecCore; const AIsReference: Boolean); overload; {$ENDREGION 'Internal Declarations'} public constructor Create; overload; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; class procedure AddToBuiltIn(const ACodec: IBLImageCodec); static; class procedure RemoveFromBuiltIn(const ACodec: IBLImageCodec); static; class property BuiltInCodecs: TArray read GetBuiltInCodecs; end; {$ENDREGION 'Image Codec'} {$REGION 'Pattern'} { ============================================================================ [BLPattern] ============================================================================ } type { Pattern } IBLPattern = interface ['{BE559BED-3495-49D7-AB00-7BF092E1F53B}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetImage: IBLImage; procedure SetImage(const AValue: IBLImage); overload; function GetArea: TBLRectI; procedure SetArea(const AValue: TBLRectI); function GetExtendMode: TBLExtendMode; procedure SetExtendMode(const AValue: TBLExtendMode); function GetHasMatrix: Boolean; function GetMatrixType: TBLMatrix2DType; function GetMatrix: TBLMatrix2D; procedure SetMatrix(const AValue: TBLMatrix2D); function GetHandle: PBLPatternCore; {$ENDREGION 'Internal Declarations'} procedure Initialize(const AImage: IBLImage; const AExtendMode: TBLExtendMode = TBLExtendMode.&Repeat); overload; procedure Initialize(const AImage: IBLImage; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); overload; procedure Initialize(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode = TBLExtendMode.&Repeat); overload; procedure Initialize(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); overload; procedure Reset; function Equals(const AOther: IBLPattern): Boolean; procedure SetImage(const AValue: IBLImage; const AArea: TBLRectI); overload; procedure ResetImage; procedure ResetArea; procedure ResetExtendMode; procedure ResetMatrix; procedure Translate(const AX, AY: Double); overload; procedure Translate(const AP: TBLPoint); overload; procedure Translate(const AP: TBLPointI); overload; procedure Scale(const AXY: Double); overload; procedure Scale(const AX, AY: Double); overload; procedure Scale(const AP: TBLPoint); overload; procedure Scale(const AP: TBLPointI); overload; procedure Skew(const AX, AY: Double); overload; procedure Skew(const AP: TBLPoint); overload; procedure Rotate(const AAngle: Double); overload; procedure Rotate(const AAngle, AX, AY: Double); overload; procedure Rotate(const AAngle: Double; const AP: TBLPoint); overload; procedure Rotate(const AAngle: Double; const AP: TBLPointI); overload; procedure Transform(const AMatrix: TBLMatrix2D); procedure PostTranslate(const AX, AY: Double); overload; procedure PostTranslate(const AP: TBLPoint); overload; procedure PostTranslate(const AP: TBLPointI); overload; procedure PostScale(const AXY: Double); overload; procedure PostScale(const AX, AY: Double); overload; procedure PostScale(const AP: TBLPoint); overload; procedure PostScale(const AP: TBLPointI); overload; procedure PostSkew(const AX, AY: Double); overload; procedure PostSkew(const AP: TBLPoint); overload; procedure PostRotate(const AAngle: Double); overload; procedure PostRotate(const AAngle, AX, AY: Double); overload; procedure PostRotate(const AAngle: Double; const AP: TBLPoint); overload; procedure PostRotate(const AAngle: Double; const AP: TBLPointI); overload; procedure PostTransform(const AMatrix: TBLMatrix2D); { Whether the pattern is a built-in null instance. } property IsNone: Boolean read GetIsNone; property Image: IBLImage read GetImage write SetImage; property Area: TBLRectI read GetArea write SetArea; property ExtendMode: TBLExtendMode read GetExtendMode write SetExtendMode; property HasMatrix: Boolean read GetHasMatrix; property MatrixType: TBLMatrix2DType read GetMatrixType; property Matrix: TBLMatrix2D read GetMatrix write SetMatrix; { Internal handle for use with the C API } property Handle: PBLPatternCore read GetHandle; end; type { Implements IBLPattern } TBLPattern = class(TInterfacedObject, IBLPattern) {$REGION 'Internal Declarations'} private FHandle: BLPatternCore; FImage: IBLImage; FIsReference: Boolean; protected { IBLPattern } function GetIsNone: Boolean; function GetImage: IBLImage; procedure SetImage(const AValue: IBLImage); overload; function GetArea: TBLRectI; procedure SetArea(const AValue: TBLRectI); function GetExtendMode: TBLExtendMode; procedure SetExtendMode(const AValue: TBLExtendMode); function GetHasMatrix: Boolean; function GetMatrixType: TBLMatrix2DType; function GetMatrix: TBLMatrix2D; procedure SetMatrix(const AValue: TBLMatrix2D); function GetHandle: PBLPatternCore; procedure Initialize(const AImage: IBLImage; const AExtendMode: TBLExtendMode = TBLExtendMode.&Repeat); overload; procedure Initialize(const AImage: IBLImage; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); overload; procedure Initialize(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode = TBLExtendMode.&Repeat); overload; procedure Initialize(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); overload; procedure Reset; function Equals(const AOther: IBLPattern): Boolean; reintroduce; overload; procedure SetImage(const AValue: IBLImage; const AArea: TBLRectI); overload; procedure ResetImage; procedure ResetArea; procedure ResetExtendMode; procedure ResetMatrix; procedure Translate(const AX, AY: Double); overload; procedure Translate(const AP: TBLPoint); overload; procedure Translate(const AP: TBLPointI); overload; procedure Scale(const AXY: Double); overload; procedure Scale(const AX, AY: Double); overload; procedure Scale(const AP: TBLPoint); overload; procedure Scale(const AP: TBLPointI); overload; procedure Skew(const AX, AY: Double); overload; procedure Skew(const AP: TBLPoint); overload; procedure Rotate(const AAngle: Double); overload; procedure Rotate(const AAngle, AX, AY: Double); overload; procedure Rotate(const AAngle: Double; const AP: TBLPoint); overload; procedure Rotate(const AAngle: Double; const AP: TBLPointI); overload; procedure Transform(const AMatrix: TBLMatrix2D); procedure PostTranslate(const AX, AY: Double); overload; procedure PostTranslate(const AP: TBLPoint); overload; procedure PostTranslate(const AP: TBLPointI); overload; procedure PostScale(const AXY: Double); overload; procedure PostScale(const AX, AY: Double); overload; procedure PostScale(const AP: TBLPoint); overload; procedure PostScale(const AP: TBLPointI); overload; procedure PostSkew(const AX, AY: Double); overload; procedure PostSkew(const AP: TBLPoint); overload; procedure PostRotate(const AAngle: Double); overload; procedure PostRotate(const AAngle, AX, AY: Double); overload; procedure PostRotate(const AAngle: Double; const AP: TBLPoint); overload; procedure PostRotate(const AAngle: Double; const AP: TBLPointI); overload; procedure PostTransform(const AMatrix: TBLMatrix2D); private constructor Create(const AHandle: BLPatternCore; const AIsReference: Boolean); overload; {$ENDREGION 'Internal Declarations'} public constructor Create; overload; constructor Create(const AImage: IBLImage; const AExtendMode: TBLExtendMode = TBLExtendMode.&Repeat); overload; constructor Create(const AImage: IBLImage; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); overload; constructor Create(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode = TBLExtendMode.&Repeat); overload; constructor Create(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); overload; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; {$ENDREGION 'Pattern'} {$REGION 'Font Defs'} { ============================================================================ [Enums] ============================================================================ } type { Placement of glyphs stored in a TBLGlyphRun. } TBLGlyphPlacementType = ( { No placement (custom handling by TBLPathSinkEvent). } None = BL_GLYPH_PLACEMENT_TYPE_NONE, { Each glyph has a TBLGlyphPlacement (advance + offset). } AdvanceOffset = BL_GLYPH_PLACEMENT_TYPE_ADVANCE_OFFSET, { Each glyph has a TBLPoint offset in design-space units. } DesignUnits = BL_GLYPH_PLACEMENT_TYPE_DESIGN_UNITS, { Each glyph has a TBLPoint offset in user-space units. } UserUnits = BL_GLYPH_PLACEMENT_TYPE_USER_UNITS, { Each glyph has a TBLPoint offset in absolute units. } AbsoluteUnits = BL_GLYPH_PLACEMENT_TYPE_ABSOLUTE_UNITS); type TBLGlyphRunFlag = ( _Dummy = 0, { Glyph-run contains USC-4 string and not glyphs (glyph-buffer only). } UCS4Content = 28, { Glyph-run was created from text that was not a valid unicode. } InvalidText = 29, { Not the whole text was mapped to glyphs (contains undefined glyphs). } UndefinedGlyphs = 30, { Encountered invalid font-data during text / glyph processing. } InvalidFontData = 31); TBLGlyphRunFlags = set of TBLGlyphRunFlag; type { Font-data flags. } TBLFontDataFlag = ( { Font data references a font-collection. } Collection = 0); TBLFontDataFlags = set of TBLFontDataFlag; type { Type of a font or font-face. } TBLFontFaceType = ( None = BL_FONT_FACE_TYPE_NONE, { TrueType/OpenType font type. } OpenType = BL_FONT_FACE_TYPE_OPENTYPE); type TBLFontFaceFlag = ( { Font uses typographic family and subfamily names. } TypographicNames = 0, { Font uses typographic metrics. } TypographicMetrics = 1, { Character to glyph mapping is available. } CharToGlyphMapping = 2, { Horizontal glyph metrics (advances, side bearings) is available. } HorizontalMetrics = 4, { Vertical glyph metrics (advances, side bearings) is available. } VerticalMetrics = 5, { Legacy horizontal kerning feature ('kern' table with horizontal kerning data). } HorizontalKerning = 6, { Legacy vertical kerning feature ('kern' table with vertical kerning data). } VerticalKerning = 7, { OpenType features (GDEF, GPOS, GSUB) are available. } OpenTypeFeatures = 8, { Panose classification is available. } PanoseData = 9, { Unicode coverage information is available. } UnicodeCoverage = 10, { Baseline for font at `y` equals 0. } BaselineYEquals0 = 12, { Left sidebearing point at `x == 0` (TT only). } LSBPointXEquals0 = 13, { Unicode variation sequences feature is available. } VariationSequences = 28, { OpenType Font Variations feature is available. } OpenTypeVariations = 29, { This is a symbol font. } SymbolFont = 30, { This is a last resort font. } LastResortFont = 31); TBLFontFaceFlags = set of TBLFontFaceFlag; type TBLFontFaceDiagFlag = ( { Wrong data in 'name' table. } WrongNameData = 0, { Fixed data read from 'name' table and possibly fixed font family/subfamily name. } FixedNameData = 1, { Wrong data in 'kern' table [kerning disabled]. } WrongKernData = 2, { Fixed data read from 'kern' table so it can be used. } FixedKernData = 3, { Wrong data in 'cmap' table. } WrongCMAPData = 4, { Wrong format in 'cmap' (sub)table. } WrongCMAPFormat = 5, { Wrong data in 'GDEF' table. } WrongGDEFData = 8, { Wrong data in 'GPOS' table. } WrongGPOSData = 10, { Wrong data in 'GSUB' table. } WrongGSUBData = 12); TBLFontFaceDiagFlags = set of TBLFontFaceDiagFlag; type { Format of an outline stored in a font. } TBLFontOutlineType = ( { None. } None = BL_FONT_OUTLINE_TYPE_NONE, { TrueType outlines. } TrueType = BL_FONT_OUTLINE_TYPE_TRUETYPE, { OpenType (CFF) outlines. } CFF = BL_FONT_OUTLINE_TYPE_CFF, { OpenType (CFF2) outlines (font variations support). } CFF2 = BL_FONT_OUTLINE_TYPE_CFF2); type { Font stretch. } TBLFontStretch = ( { Ultra condensed stretch. } UltraCondensed = BL_FONT_STRETCH_ULTRA_CONDENSED, { Extra condensed stretch. } ExtraCondensed = BL_FONT_STRETCH_EXTRA_CONDENSED, { Condensed stretch. } Condensed = BL_FONT_STRETCH_CONDENSED, { Semi condensed stretch. } SemiCondensed = BL_FONT_STRETCH_SEMI_CONDENSED, { Normal stretch. } Normal = BL_FONT_STRETCH_NORMAL, { Semi expanded stretch. } SemiExpanded = BL_FONT_STRETCH_SEMI_EXPANDED, { Expanded stretch. } Expanded = BL_FONT_STRETCH_EXPANDED, { Extra expanded stretch. } ExtraExpanded = BL_FONT_STRETCH_EXTRA_EXPANDED, { Ultra expanded stretch. } UltraExpanded = BL_FONT_STRETCH_ULTRA_EXPANDED); type { Font style. } TBLFontStyle = ( { Normal style. } Normal = BL_FONT_STYLE_NORMAL, { Oblique. } Oblique = BL_FONT_STYLE_OBLIQUE, { Italic. } Italic = BL_FONT_STYLE_ITALIC); type { Font weight. } TBLFontWeight = ( { Thin weight (100). } Thin = BL_FONT_WEIGHT_THIN, { Extra light weight (200). } ExtraLight = BL_FONT_WEIGHT_EXTRA_LIGHT, { Light weight (300). } Light = BL_FONT_WEIGHT_LIGHT, { Semi light weight (350). } SemiLight = BL_FONT_WEIGHT_SEMI_LIGHT, { Normal weight (400). } Normal = BL_FONT_WEIGHT_NORMAL, { Medium weight (500). } Medium = BL_FONT_WEIGHT_MEDIUM, { Semi bold weight (600). } SemiBold = BL_FONT_WEIGHT_SEMI_BOLD, { Bold weight (700). } Bold = BL_FONT_WEIGHT_BOLD, { Extra bold weight (800). } ExtraBold = BL_FONT_WEIGHT_EXTRA_BOLD, { Black weight (900). } Black = BL_FONT_WEIGHT_BLACK, { Extra black weight (950). } ExtraBlack = BL_FONT_WEIGHT_EXTRA_BLACK); type { Font string identifiers used by OpenType 'name' table. } TBLFontStringId = ( { Copyright notice. } CopyrightNotice = BL_FONT_STRING_COPYRIGHT_NOTICE, { Font family name. } FamilyName = BL_FONT_STRING_FAMILY_NAME, { Font subfamily name. } SubfamilyName = BL_FONT_STRING_SUBFAMILY_NAME, { Unique font identifier. } UniqueIdentifier = BL_FONT_STRING_UNIQUE_IDENTIFIER, { Full font name that reflects all family and relevant subfamily descriptors. } FullName = BL_FONT_STRING_FULL_NAME, { Version string. Should begin with the synta `Version .`. } VersionString = BL_FONT_STRING_VERSION_STRING, { PostScript name for the font. } PostScriptName = BL_FONT_STRING_POST_SCRIPT_NAME, { Trademark notice/information for this font. } Trademark = BL_FONT_STRING_TRADEMARK, { Manufacturer name. } ManufacturerName = BL_FONT_STRING_MANUFACTURER_NAME, { Name of the designer of the typeface. } DesignerName = BL_FONT_STRING_DESIGNER_NAME, { Description of the typeface. } Description = BL_FONT_STRING_DESCRIPTION, { URL of font vendor. } VendorURL = BL_FONT_STRING_VENDOR_URL, { URL of typeface designer. } DesignerURL = BL_FONT_STRING_DESIGNER_URL, { Description of how the font may be legally used. } LicenseDescription = BL_FONT_STRING_LICENSE_DESCRIPTION, { URL where additional licensing information can be found. } LicenseInfoURL = BL_FONT_STRING_LICENSE_INFO_URL, { Reserved. } Reserved = BL_FONT_STRING_RESERVED, { Typographic family name. } TypographicFamilyName = BL_FONT_STRING_TYPOGRAPHIC_FAMILY_NAME, { Typographic subfamily name. } TypographicSubfamilyName = BL_FONT_STRING_TYPOGRAPHIC_SUBFAMILY_NAME, { Compatible full name (MAC only). } CompatibleFullName = BL_FONT_STRING_COMPATIBLE_FULL_NAME, { Sample text - font name or any other text from the designer. } SampleText = BL_FONT_STRING_SAMPLE_TEXT, { PostScript CID findfont name. } PostScriptCIDName = BL_FONT_STRING_POST_SCRIPT_CID_NAME, { WWS family name. } WWSFamilyName = BL_FONT_STRING_WWS_FAMILY_NAME, { WWS subfamily name. } WWSSubfamilyName = BL_FONT_STRING_WWS_SUBFAMILY_NAME, { Light background palette. } LightBackgroundPalette = BL_FONT_STRING_LIGHT_BACKGROUND_PALETTE, { Dark background palette. } DarkBackgroundPalette = BL_FONT_STRING_DARK_BACKGROUND_PALETTE, { Variations PostScript name prefix. } VariationsPostSciptPrefix = BL_FONT_STRING_VARIATIONS_POST_SCRIPT_PREFIX); type { Bit positions in TBLFontUnicodeCoverage record. Each bit represents a range (or multiple ranges) of unicode characters. } TBLFontUnicodeCoverageIndex = ( BasicLatin = BL_FONT_UC_INDEX_BASIC_LATIN, // [000000-00007F] Basic Latin. Latin1Supplement = BL_FONT_UC_INDEX_LATIN1_SUPPLEMENT, // [000080-0000FF] Latin-1 Supplement. LatinExtendedA = BL_FONT_UC_INDEX_LATIN_EXTENDED_A, // [000100-00017F] Latin Extended-A. LatinExtendedB = BL_FONT_UC_INDEX_LATIN_EXTENDED_B, // [000180-00024F] Latin Extended-B. IPAExtensions = BL_FONT_UC_INDEX_IPA_EXTENSIONS, // [000250-0002AF] IPA Extensions. // [001D00-001D7F] Phonetic Extensions. // [001D80-001DBF] Phonetic Extensions Supplement. SpacingModifierLetters = BL_FONT_UC_INDEX_SPACING_MODIFIER_LETTERS, // [0002B0-0002FF] Spacing Modifier Letters. // [00A700-00A71F] Modifier Tone Letters. // [001DC0-001DFF] Combining Diacritical Marks Supplement. CombiningDiacriticalMarks = BL_FONT_UC_INDEX_COMBINING_DIACRITICAL_MARKS, // [000300-00036F] Combining Diacritical Marks. GreekAndCoptic = BL_FONT_UC_INDEX_GREEK_AND_COPTIC, // [000370-0003FF] Greek and Coptic. Coptic = BL_FONT_UC_INDEX_COPTIC, // [002C80-002CFF] Coptic. Cyrillic = BL_FONT_UC_INDEX_CYRILLIC, // [000400-0004FF] Cyrillic. // [000500-00052F] Cyrillic Supplement. // [002DE0-002DFF] Cyrillic Extended-A. // [00A640-00A69F] Cyrillic Extended-B. Armenian = BL_FONT_UC_INDEX_ARMENIAN, // [000530-00058F] Armenian. Hebrew = BL_FONT_UC_INDEX_HEBREW, // [000590-0005FF] Hebrew. Vai = BL_FONT_UC_INDEX_VAI, // [00A500-00A63F] Vai. Arabic = BL_FONT_UC_INDEX_ARABIC, // [000600-0006FF] Arabic. // [000750-00077F] Arabic Supplement. NKo = BL_FONT_UC_INDEX_NKO, // [0007C0-0007FF] NKo. Devanagari = BL_FONT_UC_INDEX_DEVANAGARI, // [000900-00097F] Devanagari. Bengali = BL_FONT_UC_INDEX_BENGALI, // [000980-0009FF] Bengali. Gurmukhi = BL_FONT_UC_INDEX_GURMUKHI, // [000A00-000A7F] Gurmukhi. Gujarati = BL_FONT_UC_INDEX_GUJARATI, // [000A80-000AFF] Gujarati. Oriya = BL_FONT_UC_INDEX_ORIYA, // [000B00-000B7F] Oriya. Tamil = BL_FONT_UC_INDEX_TAMIL, // [000B80-000BFF] Tamil. Telugu = BL_FONT_UC_INDEX_TELUGU, // [000C00-000C7F] Telugu. Kannada = BL_FONT_UC_INDEX_KANNADA, // [000C80-000CFF] Kannada. Malayalam = BL_FONT_UC_INDEX_MALAYALAM, // [000D00-000D7F] Malayalam. Thai = BL_FONT_UC_INDEX_THAI, // [000E00-000E7F] Thai. Lao = BL_FONT_UC_INDEX_LAO, // [000E80-000EFF] Lao. Georgian = BL_FONT_UC_INDEX_GEORGIAN, // [0010A0-0010FF] Georgian. // [002D00-002D2F] Georgian Supplement. Balinese = BL_FONT_UC_INDEX_BALINESE, // [001B00-001B7F] Balinese. HangulJamo = BL_FONT_UC_INDEX_HANGUL_JAMO, // [001100-0011FF] Hangul Jamo. LatinExtendedAdditional = BL_FONT_UC_INDEX_LATIN_EXTENDED_ADDITIONAL, // [001E00-001EFF] Latin Extended Additional. // [002C60-002C7F] Latin Extended-C. // [00A720-00A7FF] Latin Extended-D. GreekExtended = BL_FONT_UC_INDEX_GREEK_EXTENDED, // [001F00-001FFF] Greek Extended. GeneralPunctuation = BL_FONT_UC_INDEX_GENERAL_PUNCTUATION, // [002000-00206F] General Punctuation. // [002E00-002E7F] Supplemental Punctuation. SuperscriptsAndSubscripts = BL_FONT_UC_INDEX_SUPERSCRIPTS_AND_SUBSCRIPTS, // [002070-00209F] Superscripts And Subscripts. CurrencySymbols = BL_FONT_UC_INDEX_CURRENCY_SYMBOLS, // [0020A0-0020CF] Currency Symbols. CombiningDiacriticalMarksForSymbols = BL_FONT_UC_INDEX_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS, // [0020D0-0020FF] Combining Diacritical Marks For Symbols. LetterlikeSymbols = BL_FONT_UC_INDEX_LETTERLIKE_SYMBOLS, // [002100-00214F] Letterlike Symbols. NumberForms = BL_FONT_UC_INDEX_NUMBER_FORMS, // [002150-00218F] Number Forms. Arrows = BL_FONT_UC_INDEX_ARROWS, // [002190-0021FF] Arrows. // [0027F0-0027FF] Supplemental Arrows-A. // [002900-00297F] Supplemental Arrows-B. // [002B00-002BFF] Miscellaneous Symbols and Arrows. MathematicalOperators = BL_FONT_UC_INDEX_MATHEMATICAL_OPERATORS, // [002200-0022FF] Mathematical Operators. // [002A00-002AFF] Supplemental Mathematical Operators. // [0027C0-0027EF] Miscellaneous Mathematical Symbols-A. // [002980-0029FF] Miscellaneous Mathematical Symbols-B. MiscellaneousTechnical = BL_FONT_UC_INDEX_MISCELLANEOUS_TECHNICAL, // [002300-0023FF] Miscellaneous Technical. ControlPictures = BL_FONT_UC_INDEX_CONTROL_PICTURES, // [002400-00243F] Control Pictures. OpticalCharacterRecognition = BL_FONT_UC_INDEX_OPTICAL_CHARACTER_RECOGNITION, // [002440-00245F] Optical Character Recognition. EnclosedAlphanumerics = BL_FONT_UC_INDEX_ENCLOSED_ALPHANUMERICS, // [002460-0024FF] Enclosed Alphanumerics. BoxDrawing = BL_FONT_UC_INDEX_BOX_DRAWING, // [002500-00257F] Box Drawing. BlockElements = BL_FONT_UC_INDEX_BLOCK_ELEMENTS, // [002580-00259F] Block Elements. GeometricShapes = BL_FONT_UC_INDEX_GEOMETRIC_SHAPES, // [0025A0-0025FF] Geometric Shapes. MiscellaneousSymbols = BL_FONT_UC_INDEX_MISCELLANEOUS_SYMBOLS, // [002600-0026FF] Miscellaneous Symbols. Dingbats = BL_FONT_UC_INDEX_DINGBATS, // [002700-0027BF] Dingbats. CJKSymbolsAndPunctuation = BL_FONT_UC_INDEX_CJK_SYMBOLS_AND_PUNCTUATION, // [003000-00303F] CJK Symbols And Punctuation. Hiragana = BL_FONT_UC_INDEX_HIRAGANA, // [003040-00309F] Hiragana. Katakana = BL_FONT_UC_INDEX_KATAKANA, // [0030A0-0030FF] Katakana. // [0031F0-0031FF] Katakana Phonetic Extensions. Bopomofo = BL_FONT_UC_INDEX_BOPOMOFO, // [003100-00312F] Bopomofo. // [0031A0-0031BF] Bopomofo Extended. HangulCompatibilityJamo = BL_FONT_UC_INDEX_HANGUL_COMPATIBILITY_JAMO, // [003130-00318F] Hangul Compatibility Jamo. PhagsPa = BL_FONT_UC_INDEX_PHAGS_PA, // [00A840-00A87F] Phags-pa. EnclosedCJKLettersAndMonths = BL_FONT_UC_INDEX_ENCLOSED_CJK_LETTERS_AND_MONTHS, // [003200-0032FF] Enclosed CJK Letters And Months. CJKCompatibility = BL_FONT_UC_INDEX_CJK_COMPATIBILITY, // [003300-0033FF] CJK Compatibility. HangulSyllables = BL_FONT_UC_INDEX_HANGUL_SYLLABLES, // [00AC00-00D7AF] Hangul Syllables. NonPlane = BL_FONT_UC_INDEX_NON_PLANE, // [00D800-00DFFF] Non-Plane 0 *. Phoenician = BL_FONT_UC_INDEX_PHOENICIAN, // [010900-01091F] Phoenician. CJKUnifiedIdeographs = BL_FONT_UC_INDEX_CJK_UNIFIED_IDEOGRAPHS, // [004E00-009FFF] CJK Unified Ideographs. // [002E80-002EFF] CJK Radicals Supplement. // [002F00-002FDF] Kangxi Radicals. // [002FF0-002FFF] Ideographic Description Characters. // [003400-004DBF] CJK Unified Ideographs Extension A. // [020000-02A6DF] CJK Unified Ideographs Extension B. // [003190-00319F] Kanbun. PrivateUsePlane0 = BL_FONT_UC_INDEX_PRIVATE_USE_PLANE0, // [00E000-00F8FF] Private Use (Plane 0). CJKStrokes = BL_FONT_UC_INDEX_CJK_STROKES, // [0031C0-0031EF] CJK Strokes. // [00F900-00FAFF] CJK Compatibility Ideographs. // [02F800-02FA1F] CJK Compatibility Ideographs Supplement. AlphabeticPresentationForms = BL_FONT_UC_INDEX_ALPHABETIC_PRESENTATION_FORMS, // [00FB00-00FB4F] Alphabetic Presentation Forms. ArabicPresentationsFormsA = BL_FONT_UC_INDEX_ARABIC_PRESENTATION_FORMS_A, // [00FB50-00FDFF] Arabic Presentation Forms-A. CombiningHalfMarks = BL_FONT_UC_INDEX_COMBINING_HALF_MARKS, // [00FE20-00FE2F] Combining Half Marks. VerticalForms = BL_FONT_UC_INDEX_VERTICAL_FORMS, // [00FE10-00FE1F] Vertical Forms. // [00FE30-00FE4F] CJK Compatibility Forms. SmallFormVariants = BL_FONT_UC_INDEX_SMALL_FORM_VARIANTS, // [00FE50-00FE6F] Small Form Variants. ArabicPresentationFormsB = BL_FONT_UC_INDEX_ARABIC_PRESENTATION_FORMS_B, // [00FE70-00FEFF] Arabic Presentation Forms-B. HalfwidthAndFullwidthForms = BL_FONT_UC_INDEX_HALFWIDTH_AND_FULLWIDTH_FORMS, // [00FF00-00FFEF] Halfwidth And Fullwidth Forms. Specials = BL_FONT_UC_INDEX_SPECIALS, // [00FFF0-00FFFF] Specials. Tibetan = BL_FONT_UC_INDEX_TIBETAN, // [000F00-000FFF] Tibetan. Syriac = BL_FONT_UC_INDEX_SYRIAC, // [000700-00074F] Syriac. Thaana = BL_FONT_UC_INDEX_THAANA, // [000780-0007BF] Thaana. Sinhala = BL_FONT_UC_INDEX_SINHALA, // [000D80-000DFF] Sinhala. Myanmar = BL_FONT_UC_INDEX_MYANMAR, // [001000-00109F] Myanmar. Ethiopic = BL_FONT_UC_INDEX_ETHIOPIC, // [001200-00137F] Ethiopic. // [001380-00139F] Ethiopic Supplement. // [002D80-002DDF] Ethiopic Extended. Cherokee = BL_FONT_UC_INDEX_CHEROKEE, // [0013A0-0013FF] Cherokee. UnifiedCanadianAboriginalSyllabics = BL_FONT_UC_INDEX_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, // [001400-00167F] Unified Canadian Aboriginal Syllabics. Ogham = BL_FONT_UC_INDEX_OGHAM, // [001680-00169F] Ogham. Runic = BL_FONT_UC_INDEX_RUNIC, // [0016A0-0016FF] Runic. Khmer = BL_FONT_UC_INDEX_KHMER, // [001780-0017FF] Khmer. // [0019E0-0019FF] Khmer Symbols. Mongolian = BL_FONT_UC_INDEX_MONGOLIAN, // [001800-0018AF] Mongolian. BraillePatterns = BL_FONT_UC_INDEX_BRAILLE_PATTERNS, // [002800-0028FF] Braille Patterns. YiSyllablesAndRadicals = BL_FONT_UC_INDEX_YI_SYLLABLES_AND_RADICALS, // [00A000-00A48F] Yi Syllables. // [00A490-00A4CF] Yi Radicals. TagalogHanunooBuhidTagbanwa = BL_FONT_UC_INDEX_TAGALOG_HANUNOO_BUHID_TAGBANWA, // [001700-00171F] Tagalog. // [001720-00173F] Hanunoo. // [001740-00175F] Buhid. // [001760-00177F] Tagbanwa. OldItalic = BL_FONT_UC_INDEX_OLD_ITALIC, // [010300-01032F] Old Italic. Gothic = BL_FONT_UC_INDEX_GOTHIC, // [010330-01034F] Gothic. Deseret = BL_FONT_UC_INDEX_DESERET, // [010400-01044F] Deseret. MusicalSymbols = BL_FONT_UC_INDEX_MUSICAL_SYMBOLS, // [01D000-01D0FF] Byzantine Musical Symbols. // [01D100-01D1FF] Musical Symbols. // [01D200-01D24F] Ancient Greek Musical Notation. MathematicalAlphanumericSymbols = BL_FONT_UC_INDEX_MATHEMATICAL_ALPHANUMERIC_SYMBOLS, // [01D400-01D7FF] Mathematical Alphanumeric Symbols. PrivateUsePlane15And16 = BL_FONT_UC_INDEX_PRIVATE_USE_PLANE_15_16, // [0F0000-0FFFFD] Private Use (Plane 15). // [100000-10FFFD] Private Use (Plane 16). VariationSelectors = BL_FONT_UC_INDEX_VARIATION_SELECTORS, // [00FE00-00FE0F] Variation Selectors. // [0E0100-0E01EF] Variation Selectors Supplement. Tags = BL_FONT_UC_INDEX_TAGS, // [0E0000-0E007F] Tags. Limbu = BL_FONT_UC_INDEX_LIMBU, // [001900-00194F] Limbu. TaiLe = BL_FONT_UC_INDEX_TAI_LE, // [001950-00197F] Tai Le. NewTaiLue = BL_FONT_UC_INDEX_NEW_TAI_LUE, // [001980-0019DF] New Tai Lue. Buginese = BL_FONT_UC_INDEX_BUGINESE, // [001A00-001A1F] Buginese. Glagolitic = BL_FONT_UC_INDEX_GLAGOLITIC, // [002C00-002C5F] Glagolitic. Tifinagh = BL_FONT_UC_INDEX_TIFINAGH, // [002D30-002D7F] Tifinagh. YijingHexagramSymbols = BL_FONT_UC_INDEX_YIJING_HEXAGRAM_SYMBOLS, // [004DC0-004DFF] Yijing Hexagram Symbols. SylotiNagri = BL_FONT_UC_INDEX_SYLOTI_NAGRI, // [00A800-00A82F] Syloti Nagri. LinearBSyllabaryAndIdeograms = BL_FONT_UC_INDEX_LINEAR_B_SYLLABARY_AND_IDEOGRAMS, // [010000-01007F] Linear B Syllabary. // [010080-0100FF] Linear B Ideograms. // [010100-01013F] Aegean Numbers. AncientGreekNumbers = BL_FONT_UC_INDEX_ANCIENT_GREEK_NUMBERS, // [010140-01018F] Ancient Greek Numbers. Ugaritic = BL_FONT_UC_INDEX_UGARITIC, // [010380-01039F] Ugaritic. OldPersian = BL_FONT_UC_INDEX_OLD_PERSIAN, // [0103A0-0103DF] Old Persian. Shavian = BL_FONT_UC_INDEX_SHAVIAN, // [010450-01047F] Shavian. Osmanya = BL_FONT_UC_INDEX_OSMANYA, // [010480-0104AF] Osmanya. CypriotSyllabary = BL_FONT_UC_INDEX_CYPRIOT_SYLLABARY, // [010800-01083F] Cypriot Syllabary. Kharoshthi = BL_FONT_UC_INDEX_KHAROSHTHI, // [010A00-010A5F] Kharoshthi. TaiXuanJingSymbols = BL_FONT_UC_INDEX_TAI_XUAN_JING_SYMBOLS, // [01D300-01D35F] Tai Xuan Jing Symbols. Cuneiform = BL_FONT_UC_INDEX_CUNEIFORM, // [012000-0123FF] Cuneiform. // [012400-01247F] Cuneiform Numbers and Punctuation. CountingRodNumerals = BL_FONT_UC_INDEX_COUNTING_ROD_NUMERALS, // [01D360-01D37F] Counting Rod Numerals. Sundanese = BL_FONT_UC_INDEX_SUNDANESE, // [001B80-001BBF] Sundanese. Lepcha = BL_FONT_UC_INDEX_LEPCHA, // [001C00-001C4F] Lepcha. OlChiki = BL_FONT_UC_INDEX_OL_CHIKI, // [001C50-001C7F] Ol Chiki. Saurashtra = BL_FONT_UC_INDEX_SAURASHTRA, // [00A880-00A8DF] Saurashtra. KayahLi = BL_FONT_UC_INDEX_KAYAH_LI, // [00A900-00A92F] Kayah Li. Rejang = BL_FONT_UC_INDEX_REJANG, // [00A930-00A95F] Rejang. Cham = BL_FONT_UC_INDEX_CHAM, // [00AA00-00AA5F] Cham. AncientSymbols = BL_FONT_UC_INDEX_ANCIENT_SYMBOLS, // [010190-0101CF] Ancient Symbols. PhaistosDisc = BL_FONT_UC_INDEX_PHAISTOS_DISC, // [0101D0-0101FF] Phaistos Disc. CarianLycianLydian = BL_FONT_UC_INDEX_CARIAN_LYCIAN_LYDIAN, // [0102A0-0102DF] Carian. // [010280-01029F] Lycian. // [010920-01093F] Lydian. DominoAndMahjongTiles = BL_FONT_UC_INDEX_DOMINO_AND_MAHJONG_TILES, // [01F030-01F09F] Domino Tiles. // [01F000-01F02F] Mahjong Tiles. InternalUsage123 = BL_FONT_UC_INDEX_INTERNAL_USAGE_123, // Reserved for internal usage (123). InternalUsage124 = BL_FONT_UC_INDEX_INTERNAL_USAGE_124, // Reserved for internal usage (124). InternalUsage125 = BL_FONT_UC_INDEX_INTERNAL_USAGE_125, // Reserved for internal usage (125). InternalUsage126 = BL_FONT_UC_INDEX_INTERNAL_USAGE_126, // Reserved for internal usage (126). InternalUsage127 = BL_FONT_UC_INDEX_INTERNAL_USAGE_127); // Reserved for internal usage (127). type { Text direction. } TBLTextDirection = ( { Left-to-right direction. } LTR = BL_TEXT_DIRECTION_LTR, { Right-to-left direction. } RTL = BL_TEXT_DIRECTION_RTL); type { Text orientation. } TBLTextOrientation = ( { Horizontal orientation. } Horizontal = BL_TEXT_ORIENTATION_HORIZONTAL, { Vertical orientation. } Vertical = BL_TEXT_ORIENTATION_VERTICAL); { ============================================================================ [BLGlyphInfo] ============================================================================ } type { Contains additional information associated with a glyph used by IBLGlyphBuffer. } TBLGlyphInfo = record {$REGION 'Internal Declarations'} private FHandle: BLGlyphInfo; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; property Cluster: Cardinal read FHandle.cluster write FHandle.cluster; end; PBLGlyphInfo = ^TBLGlyphInfo; { ============================================================================ [BLGlyphPlacement] ============================================================================ } type { Glyph placement. Provides information about glyph offset (x/y) and advance (x/y). } TBLGlyphPlacement = record {$REGION 'Internal Declarations'} private FHandle: BLGlyphPlacement; function GetPlacement: TBLPointI; inline; procedure SetPlacement(const AValue: TBLPointI); inline; function GetAdvance: TBLPointI; inline; procedure SetAdvance(const AValue: TBLPointI); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; property Placement: TBLPointI read GetPlacement write SetPlacement; property Advance: TBLPointI read GetAdvance write SetAdvance; end; PBLGlyphPlacement = ^TBLGlyphPlacement; { ============================================================================ [BLGlyphMappingState] ============================================================================ } type { Character to glyph mapping state. } TBLGlyphMappingState = record {$REGION 'Internal Declarations'} private FHandle: BLGlyphMappingState; function GetGlyphCount: Integer; inline; procedure SetGlyphCount(const AValue: Integer); inline; function GetUndefinedFirst: Integer; inline; procedure SetUndefinedFirst(const AValue: Integer); inline; function GetUndefinedCount: Integer; inline; procedure SetUndefinedCount(const AValue: Integer); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; { Number of glyphs or glyph-items on output. } property GlyphCount: Integer read GetGlyphCount write SetGlyphCount; { Index of the first undefined glyph (-1 if none). } property UndefinedFirst: Integer read GetUndefinedFirst write SetUndefinedFirst; { Undefined glyph count (chars that have no mapping). } property UndefinedCount: Integer read GetUndefinedCount write SetUndefinedCount; end; PBLGlyphMappingState = ^TBLGlyphMappingState; { ============================================================================ [BLGlyphOutlineSinkInfo] ============================================================================ } type { Information passed to a TBLPathSinkEvent sink by IBLFont.GetGlyphOutlines. } TBLGlyphOutlineSinkInfo = record {$REGION 'Internal Declarations'} private FHandle: BLGlyphOutlineSinkInfo; function GetGlyphIndex: Integer; inline; procedure SetGlyphIndex(const AValue: Integer); inline; function GetContourCount: Integer; inline; procedure SetContourCount(const AValue: Integer); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; property GlyphIndex: Integer read GetGlyphIndex write SetGlyphIndex; property ContourCount: Integer read GetContourCount write SetContourCount; end; PBLGlyphOutlineSinkInfo = ^TBLGlyphOutlineSinkInfo; { ============================================================================ [BLGlyphRun] ============================================================================ } type { An entry enumerated by TBLGlyphRun.GetEnumerator } TBLGlyphRunEntry = record public { The glyph Id } GlyphId: Cardinal; { Glyph placement (type should match TBLGlyphRun.PlacementType) } Placement: TPlacement; end; type { TBLGlyphRun describes a set of consecutive glyphs and their placements. TBLGlyphRun should only be used to pass glyph IDs and their placements to the rendering context. The purpose of TBLGlyphRun is to allow rendering glyphs, which could be shaped by various shaping engines (Blend2D, Harfbuzz, etc). TBLGlyphRun allows to render glyphs that are either stored in TArray or TArray or part of a bigger structure (for example hb_glyph_info_t used by HarfBuzz). Glyph placements at the moment use Blend2D's TBLGlyphPlacement or TBLPoint, but it's possible to extend the data type in the future. See TBLGlyphRunPlacement for placement modes provided by Blend2D. } TBLGlyphRun = record {$REGION 'Internal Declarations'} private type TEnumerator = record private type P = ^T; private FGlyphData: PByte; FPlacementData: PByte; FGlyphAdvance: Integer; FPlacementAdvance: Integer; FHigh: Integer; FIndex: Integer; function GetCurrent: TBLGlyphRunEntry; inline; public constructor Create(const AHandle: _PBLGlyphRun); function MoveNext: Boolean; inline; property Current: TBLGlyphRunEntry read GetCurrent; end; private type TEnumerable = record private FHandle: _PBLGlyphRun; public constructor Create(const AHandle: _PBLGlyphRun); function GetEnumerator: TEnumerator; end; private FHandle: BLGlyphRun; function GetSize: Integer; inline; procedure SetSize(const AValue: Integer); inline; function GetPlacementType: TBLGlyphPlacementType; inline; procedure SetPlacementType(const AValue: TBLGlyphPlacementType); inline; function GetFlags: TBLGlyphRunFlags; inline; procedure SetFlags(const AValue: TBLGlyphRunFlags); inline; function GetIsEmpty: Boolean; inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; procedure SetGlyphData(const AData: PWord); overload; inline; procedure SetGlyphData(const AData: PCardinal); overload; inline; procedure SetGlyphData(const AData: Pointer; const AAdvance: Integer); overload; inline; procedure ResetGlyphIdData; inline; procedure SetPlacementData(const AData: Pointer; const AAdvance: Integer); inline; procedure ResetPlacementData; inline; { Support for..in enumeration of the glyphs in the run. The type parameter TPlacement of each entry should be a type that is compatible with the PlacementType property. Example: var GlyphRun: TBLGlyphRun; Entry: TBLGlyphRunEntry; begin GlyphRun := ...; for Entry in GlyphRun.Entries do ... end; } function Entries: TEnumerable; { Glyph id data (abstract, incremented by GlyphAdvance). } property GlyphData: Pointer read FHandle.glyphData write FHandle.glyphData; { Glyph placement data (abstract, incremented by PlacementAdvance). } property PlacementData: Pointer read FHandle.placementData write FHandle.placementData; { Size of the glyph-run in glyph units. } property Size: Integer read GetSize write SetSize; { Size of a GlyphId - must be either 2 (UInt16) or 4 (UInt32) bytes. Blend2D always uses 32-bit glyph-ids, thus the glyph-run returned by IBLGlyphBuffer has always set GlyphSize to 4. The possibility to render glyphs of size 2 is strictly for compatibility with text shapers that use 16-bit glyphs, which is sufficient for TrueType and OpenType fonts.} property GlyphSize: Byte read FHandle.glyphSize write FHandle.glyphSize; { Type of placement } property PlacementType: TBLGlyphPlacementType read GetPlacementType write SetPlacementType; { Advance of GlyphData array. } property GlyphAdvance: Shortint read FHandle.glyphAdvance write FHandle.glyphAdvance; { Glyph-run flags. } property Flags: TBLGlyphRunFlags read GetFlags write SetFlags; property IsEmpty: Boolean read GetIsEmpty; end; PBLGlyphRun = ^TBLGlyphRun; { ============================================================================ [BLFontFaceInfo] ============================================================================ } type { Information of IBLFontFace. } TBLFontFaceInfo = record {$REGION 'Internal Declarations'} private FHandle: BLFontFaceInfo; function GetFaceType: TBLFontFaceType; inline; procedure SetFaceType(const AValue: TBLFontFaceType); inline; function GetOutlineType: TBLFontOutlineType; inline; procedure SetOutlineType(const AValue: TBLFontOutlineType); inline; function GetGlyphCount: Integer; inline; procedure SetGlyphCount(const AValue: Integer); inline; function GetFaceFlags: TBLFontFaceFlags; inline; procedure SetFaceFlags(const AValue: TBLFontFaceFlags); inline; function GetDiagFlags: TBLFontFaceDiagFlags; inline; procedure SetDiagFlags(const AValue: TBLFontFaceDiagFlags); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; { Font-face type } property FaceType: TBLFontFaceType read GetFaceType write SetFaceType; { Type of outlines used by the font-face } property OutlineType: TBLFontOutlineType read GetOutlineType write SetOutlineType; { Number of glyphs provided by this font-face. } property GlyphCount: Integer read GetGlyphCount write SetGlyphCount; { Revision (read from 'head' table, represented as 16.16 fixed point). } property Revision: Cardinal read FHandle.revision write FHandle.revision; { Face-face index in a TTF/OTF collection or zero if not part of a collection. } property FaceIndex: Integer read FHandle.faceIndex write FHandle.faceIndex; { Font-face flags } property FaceFlags: TBLFontFaceFlags read GetFaceFlags write SetFaceFlags; { Font-face diagnostic flags } property DiagFlags: TBLFontFaceDiagFlags read GetDiagFlags write SetDiagFlags; end; PBLFontFaceInfo = ^TBLFontFaceInfo; { ============================================================================ [BLFontQueryProperties] ============================================================================ } type { Properties that can be used to query IBLFont and IBLFontFace. } TBLFontQueryProperties = record {$REGION 'Internal Declarations'} private FHandle: BLFontQueryProperties; function GetStyle: TBLFontStyle; inline; procedure SetStyle(const AValue: TBLFontStyle); inline; function GetWeight: TBLFontWeight; inline; procedure SetWeight(const AValue: TBLFontWeight); inline; function GetStretch: TBLFontStretch; inline; procedure SetStretch(const AValue: TBLFontStretch); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; { Font style } property Style: TBLFontStyle read GetStyle write SetStyle; { Font weight } property Weight: TBLFontWeight read GetWeight write SetWeight; { Font stretch } property Stretch: TBLFontStretch read GetStretch write SetStretch; end; { ============================================================================ [BLFontTable] ============================================================================ } type { A read only data that represents a font table or its sub-table. } TBLFontTable = record {$REGION 'Internal Declarations'} private FHandle: BLFontTable; function GetSize: Integer; inline; procedure SetSize(const AValue: Integer); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; overload; inline; procedure Reset(const AData: Pointer; const ASize: Integer); overload; inline; { Pointer to the beginning of the data } property Data: Pointer read FHandle.data write FHandle.data; { Size of Data in bytes. } property Size: Integer read GetSize write SetSize; end; PBLFontTable = ^TBLFontTable; { ============================================================================ [BLFontFeature] ============================================================================ } type { Associates a value with a generic font feature where Tag describes the feature (as provided by the font) and Value describes its value. Some features only allow boolean values 0 and 1 and some also allow higher values up to 65535. Registered OpenType features: - https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags - https://helpx.adobe.com/typekit/using/open-type-syntax.html } TBLFontFeature = record {$REGION 'Internal Declarations'} private FHandle: BLFontFeature; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; { Feature tag (32-bit). } property Tag: TBLTag read FHandle.tag write FHandle.tag; { Feature value (should not be greater than 65535). } property Value: Cardinal read FHandle.value write FHandle.value; end; PBLFontFeature = ^TBLFontFeature; { ============================================================================ [BLFontVariation] ============================================================================ } type { Associates a value with a font variation feature where Tag describes variation axis and Value defines its value. } TBLFontVariation = record {$REGION 'Internal Declarations'} private FHandle: BLFontVariation; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; { Variation tag (32-bit). } property Tag: TBLTag read FHandle.tag write FHandle.tag; { Variation value. } property Value: Single read FHandle.value write FHandle.value; end; PBLFontVariation = ^TBLFontVariation; { ============================================================================ [BLFontUnicodeCoverage] ============================================================================ } type { Font unicode coverage. Unicode coverage describes which unicode characters are provided by a font. Blend2D accesses this information by reading "OS/2" table, if available. } TBLFontUnicodeCoverage = record {$REGION 'Internal Declarations'} private FHandle: BLFontUnicodeCoverage; function GetIsEmpty: Boolean; inline; function GetBit(const AIndex: TBLFontUnicodeCoverageIndex): Boolean; procedure SetBit(const AIndex: TBLFontUnicodeCoverageIndex; const AValue: Boolean); overload; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLFontUnicodeCoverage): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLFontUnicodeCoverage): Boolean; inline; static; public procedure Reset; inline; procedure SetBit(const AIndex: TBLFontUnicodeCoverageIndex); overload; inline; procedure ClearBit(const AIndex: TBLFontUnicodeCoverageIndex); inline; property IsEmpty: Boolean read GetIsEmpty; property Bits[const AIndex: TBLFontUnicodeCoverageIndex]: Boolean read GetBit write SetBit; end; PBLFontUnicodeCoverage = ^TBLFontUnicodeCoverage; { ============================================================================ [BLFontPanose] ============================================================================ } type TBLFontPanoseText = record FamilyKind: Byte; SerifStyle: Byte; Weight: Byte; Proportion: Byte; Contrast: Byte; StrokeVariation: Byte; ArmStyle: Byte; Letterform: Byte; Midline: Byte; XHeight: Byte end; type TBLFontPanoseScript = record FamilyKind: Byte; ToolKind: Byte; Weight: Byte; Spacing: Byte; AspectRatio: Byte; Contrast: Byte; Topology: Byte; Form: Byte; Finials: Byte; XAscent: Byte; end; type TBLFontPanoseDecorative = record FamilyKind: Byte; DecorativeClass: Byte; Weight: Byte; Aspect: Byte; Contrast: Byte; SerifVariant: Byte; Treatment: Byte; Lining: Byte; Topology: Byte; CharacterRange: Byte; end; type TBLFontPanoseSymbol = record FamilyKind: Byte; SymbolKind: Byte; Weight: Byte; Spacing: Byte; AspectRatioAndContrast: Byte; AspectRatio94: Byte; AspectRatio119: Byte; AspectRatio157: Byte; AspectRatio163: Byte; AspectRatio211: Byte; end; type { Scaled TBLFontDesignMetrics based on font size and other properties. } TBLFontPanose = record {$REGION 'Internal Declarations'} private function GetIsEmpty: Boolean; inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; property IsEmpty: Boolean read GetIsEmpty; public case Integer of 0: (Data: array [0..9] of Byte); 1: (FamilyKind: Byte); 2: (Text: TBLFontPanoseText); 3: (Script: TBLFontPanoseScript); 4: (Decorative: TBLFontPanoseDecorative); 5: (Symbol: TBLFontPanoseSymbol); end; PBLFontPanose = ^TBLFontPanose; { ============================================================================ [BLFontMatrix] ============================================================================ } type { 2x2 transformation matrix used by IBLFont. It's similar to TBLMatrix2D, however, it doesn't provide a translation part as it's assumed to be zero. } TBLFontMatrix = record {$REGION 'Internal Declarations'} private FHandle: BLFontMatrix; function GetElement(const AIndex: Integer): Double; inline; procedure SetElement(const AIndex: Integer; const AValue: Double); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; overload; inline; procedure Reset(const AM00, AM01, AM10, AM11: Double); overload; inline; property Elements[const AIndex: Integer]: Double read GetElement write SetElement; default; property M00: Double read FHandle.m00 write FHandle.m00; property M01: Double read FHandle.m01 write FHandle.m01; property M10: Double read FHandle.m10 write FHandle.m10; property M11: Double read FHandle.m11 write FHandle.m11; end; PBLFontMatrix = ^TBLFontMatrix; function BLFontMatrix(const AM00, AM01, AM10, AM11: Double): TBLFontMatrix; inline; { ============================================================================ [BLFontMetrics] ============================================================================ } type { Scaled TBLFontDesignMetrics based on font size and other properties. } TBLFontMetrics = record {$REGION 'Internal Declarations'} private FHandle: BLFontMetrics; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; { Font ascent (horizontal orientation). } property Ascent: Single read FHandle.ascent write FHandle.ascent; { Font ascent (vertical orientation). } property VAscent: Single read FHandle.vAscent write FHandle.vAscent; { Font descent (horizontal orientation). } property Descent: Single read FHandle.descent write FHandle.descent; { Font descent (vertical orientation). } property VDescent: Single read FHandle.vDescent write FHandle.vDescent; { Line gap. } property LineGap: Single read FHandle.lineGap write FHandle.lineGap; { Distance between the baseline and the mean line of lower-case letters. } property XHeight: Single read FHandle.xHeight write FHandle.xHeight; { Maximum height of a capital letter above the baseline.} property CapHeight: Single read FHandle.capHeight write FHandle.capHeight; { Minimum x, reported by the font. } property XMin: Single read FHandle.xMin write FHandle.xMin; { Minimum y, reported by the font. } property YMin: Single read FHandle.yMin write FHandle.yMin; { Maximum x, reported by the font. } property XMax: Single read FHandle.xMax write FHandle.xMax; { Maximum y, reported by the font. } property YMax: Single read FHandle.yMax write FHandle.yMax; { Text underline position. } property UnderlinePosition: Single read FHandle.underlinePosition write FHandle.underlinePosition; { Text underline thickness. } property UnderlineThickness: Single read FHandle.underlineThickness write FHandle.underlineThickness; { Text strikethrough position. } property StrikethroughPosition: Single read FHandle.strikethroughPosition write FHandle.strikethroughPosition; { Text strikethrough thickness. } property StrikethroughThickness: Single read FHandle.strikethroughThickness write FHandle.strikethroughThickness; end; PBLFontMetrics = ^TBLFontMetrics; { ============================================================================ [BLFontDesignMetrics] ============================================================================ } type { Design metrics of a font. Design metrics is information that IBLFontFace collected directly from the font data. It means that all fields are measured in font design units. When a new IBLFont instance is created a scaled metrics IBLFontMetrics is automatically calculated from IBLFontDesignMetrics including other members like transformation, etc... } TBLFontDesignMetrics = record {$REGION 'Internal Declarations'} private FHandle: BLFontDesignMetrics; function GetGlyphBoundingBox: TBLBoxI; inline; procedure SetGlyphBoundingBox(const AValue: TBLBoxI); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; { Units per EM square. } property UnitsPerEm: Integer read FHandle.unitsPerEm write FHandle.unitsPerEm; { Lowest readable size in pixels. } property LowestPPEM: Integer read FHandle.lowestPPEM write FHandle.lowestPPEM; { Line gap. } property LineGap: Integer read FHandle.lineGap write FHandle.lineGap; { Distance between the baseline and the mean line of lower-case letters. } property XHeight: Integer read FHandle.xHeight write FHandle.xHeight; { Maximum height of a capital letter above the baseline. } property CapHeight: Integer read FHandle.capHeight write FHandle.capHeight; { Ascent (horizontal layout). } property Ascent: Integer read FHandle.ascent write FHandle.ascent; { Ascent (vertical layout). } property VAscent: Integer read FHandle.vAscent write FHandle.vAscent; { Descent (horizontal layout). } property Descent: Integer read FHandle.descent write FHandle.descent; { Descent (vertical layout). } property VDescent: Integer read FHandle.vDescent write FHandle.vDescent; { Minimum leading-side bearing (horizontal layout). } property HMinLSB: Integer read FHandle.hMinLSB write FHandle.hMinLSB; { Minimum leading-side bearing (vertical layout). } property VMinLSB: Integer read FHandle.vMinLSB write FHandle.vMinLSB; { Minimum trailing-side bearing (horizontal layout). } property HMinTSB: Integer read FHandle.hMinTSB write FHandle.hMinTSB; { Minimum trailing-side bearing (vertical layout). } property VMinTSB: Integer read FHandle.vMinTSB write FHandle.vMinTSB; { Maximum advance (horizontal layout). } property HMaxAdvance: Integer read FHandle.hMaxAdvance write FHandle.hMaxAdvance; { Maximum advance (vertical layout). } property VMaxAdvance: Integer read FHandle.vMaxAdvance write FHandle.vMaxAdvance; { Aggregated bounding box of all glyphs in the font. This value is reported by the face so it's not granted to be true. } property GlyphBoundingBox: TBLBoxI read GetGlyphBoundingBox write SetGlyphBoundingBox; { Minimum x, reported by the font. } property XMin: Integer read FHandle.glyphBoundingBox.x0 write FHandle.glyphBoundingBox.x0; { Minimum y, reported by the font. } property YMin: Integer read FHandle.glyphBoundingBox.y0 write FHandle.glyphBoundingBox.y0; { Maximum x, reported by the font. } property XMax: Integer read FHandle.glyphBoundingBox.x1 write FHandle.glyphBoundingBox.x1; { Maximum y, reported by the font. } property YMax: Integer read FHandle.glyphBoundingBox.y1 write FHandle.glyphBoundingBox.y1; { Text underline position. } property UnderlinePosition: Integer read FHandle.underlinePosition write FHandle.underlinePosition; { Text underline thickness. } property UnderlineThickness: Integer read FHandle.underlineThickness write FHandle.underlineThickness; { Text strikethrough position. } property StrikethroughPosition: Integer read FHandle.strikethroughPosition write FHandle.strikethroughPosition; { Text strikethrough thickness. } property StrikethroughThickness: Integer read FHandle.strikethroughThickness write FHandle.strikethroughThickness; end; PBLFontDesignMetrics = ^TBLFontDesignMetrics; { ============================================================================ [BLTextMetrics] ============================================================================ } type { Text metrics. } TBLTextMetrics = record {$REGION 'Internal Declarations'} private FHandle: BLTextMetrics; function GetAdvance: TBLPoint; inline; procedure SetAdvance(const AValue: TBLPoint); inline; function GetLeadingBearing: TBLPoint; inline; procedure SetLeadingBearing(const AValue: TBLPoint); inline; function GetTrailingBearing: TBLPoint; inline; procedure SetTrailingBearing(const AValue: TBLPoint); inline; function GetBoundingBox: TBLBox; inline; procedure SetBoundingBox(const AValue: TBLBox); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; property Advance: TBLPoint read GetAdvance write SetAdvance; property LeadingBearing: TBLPoint read GetLeadingBearing write SetLeadingBearing; property TrailingBearing: TBLPoint read GetTrailingBearing write SetTrailingBearing; property BoundingBox: TBLBox read GetBoundingBox write SetBoundingBox; end; PBLTextMetrics = ^TBLTextMetrics; {$ENDREGION 'Font Defs'} {$REGION 'Glyph Buffer'} { ============================================================================ [BLGlyphBuffer] ============================================================================ } type { Glyph buffer. Can hold either text or glyphs and provides basic memory management that is used for text shaping, character to glyph mapping, glyph substitution, and glyph positioning. Glyph buffer provides two separate buffers called 'primary' and 'secondary' that serve different purposes during processing. Primary buffer always holds actual text/glyph array, and secondary buffer is either used as a scratch buffer during glyph substitution or to hold glyph positions after the processing is complete and glyph positions were calculated. } IBLGlyphBuffer = interface ['{0B892B22-C3B5-434D-854C-FBD0FD431B7B}'] {$REGION 'Internal Declarations'} function GetIsEmpty: Boolean; function GetSize: Integer; function GetFlags: TBLGlyphRunFlags; function GetContent: PCardinal; function GetInfoData: PBLGlyphInfo; function GetPlacementData: PBLGlyphPlacement; function GetGlyphRun: PBLGlyphRun; function GetHasText: Boolean; function GetHasGlyphs: Boolean; function GetHasInvalidChars: Boolean; function GetHasUndefinedChars: Boolean; function GetHasInvalidFontData: Boolean; function GetHandle: PBLGlyphBufferCore; {$ENDREGION 'Internal Declarations'} { Resets the IBLGlyphBuffer into its construction state. The content will be cleared and allocated memory released. } procedure Reset; { Clears the content of IBLGlyphBuffer without releasing internal buffers. } procedure Clear; { Assigns a text content of this IBLGlyphBuffer. } procedure SetText(const AText: String); overload; procedure SetText(const AText: UTF8String); overload; procedure SetText(const AText: UCS4String); overload; { Assigns a text content of this IBLGlyphBuffer. This is a generic function that accepts Pointer data, which is specified by AEncoding. The ALength argument depends on encoding as well. If the encoding specifies byte string (Latin1 or UTF8) then it's bytes, if the encoding specifies UTF16 or UTF32 then it would describe the number of UInt16 or UInt32 code points, respectively. } procedure SetText(const AText: Pointer; const ALength: Integer; const AEncoding: TBLTextEncoding); overload; { Assigns glyph content of this IBLGlyphBuffer from the given AGlyphData. } procedure SetGlyphs(const AGlyphData: TArray); overload; procedure SetGlyphs(const AGlyphData: PCardinal; const ALength: Integer); overload; { Assigns glyph content of this IBLGlyphBuffer`from an array of glyphs or from a foreign record that contains glyphs and possibly other members that have to be skipped. The AGlyphIdSize can be either 16-bit (2) or 32-bit (4). The last parameter AGlyphAdvance specifies how many bytes to advance after a glyph value is read. } procedure SetGlyphs(const AGlyphData: Pointer; const ASize: Integer; const AGlyphIdSize, AGlyphAdvance: Integer); overload; { Tests whether the glyph-buffer has AFlag set. } function HasFlag(const AFlag: TBLGlyphRunFlag): Boolean; property IsEmpty: Boolean read GetIsEmpty; property Size: Integer read GetSize; property Flags: TBLGlyphRunFlags read GetFlags; property Content: PCardinal read GetContent; property InfoData: PBLGlyphInfo read GetInfoData; property PlacementData: PBLGlyphPlacement read GetPlacementData; property GlyphRun: PBLGlyphRun read GetGlyphRun; { Tests whether the buffer contains unicode data. } property HasText: Boolean read GetHasText; { Tests whether the buffer contains glyph-id data. } property HasGlyphs: Boolean read GetHasGlyphs; { Tests whether the input string contained invalid characters (unicode encoding errors). } property HasInvalidChars: Boolean read GetHasInvalidChars; { Tests whether the input string contained undefined characters that weren't mapped properly to glyphs. } property HasUndefinedChars: Boolean read GetHasUndefinedChars; { Tests whether one or more operation was terminated before completion because of invalid data in a font. } property HasInvalidFontData: Boolean read GetHasInvalidFontData; { Internal handle for use with the C API } property Handle: PBLGlyphBufferCore read GetHandle; end; type { Implements IBLGlyphBuffer } TBLGlyphBuffer = class(TInterfacedObject, IBLGlyphBuffer) {$REGION 'Internal Declarations'} private FHandle: BLGlyphBufferCore; protected { IBLGlyphBuffer } function GetIsEmpty: Boolean; function GetSize: Integer; function GetFlags: TBLGlyphRunFlags; function GetContent: PCardinal; function GetInfoData: PBLGlyphInfo; function GetPlacementData: PBLGlyphPlacement; function GetGlyphRun: PBLGlyphRun; function GetHasText: Boolean; function GetHasGlyphs: Boolean; function GetHasInvalidChars: Boolean; function GetHasUndefinedChars: Boolean; function GetHasInvalidFontData: Boolean; function GetHandle: PBLGlyphBufferCore; procedure Reset; procedure Clear; procedure SetText(const AText: String); overload; procedure SetText(const AText: UTF8String); overload; procedure SetText(const AText: UCS4String); overload; procedure SetText(const AText: Pointer; const ALength: Integer; const AEncoding: TBLTextEncoding); overload; procedure SetGlyphs(const AGlyphData: TArray); overload; procedure SetGlyphs(const AGlyphData: PCardinal; const ALength: Integer); overload; procedure SetGlyphs(const AGlyphData: Pointer; const ASize: Integer; const AGlyphIdSize, AGlyphAdvance: Integer); overload; function HasFlag(const AFlag: TBLGlyphRunFlag): Boolean; {$ENDREGION 'Internal Declarations'} public constructor Create; destructor Destroy; override; end; {$ENDREGION 'Glyph Buffer'} {$REGION 'Font'} { ============================================================================ [BLFontData] ============================================================================ } type IBLFontData = interface; { This event is called when IBLFontData.InitializeFromData is used and the font data is destroyed. } TBLFontDataDestroyEvent = procedure (const AFontData: IBLFontData) of object; { Font data } IBLFontData = interface ['{988C31B8-A00C-4BD0-98D9-FDF2EF6D8CAA}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetFaceType: TBLFontFaceType; function GetFaceCount: Integer; function GetFlags: TBLFontDataFlags; function GetIsCollection: Boolean; function GetHandle: PBLFontDataCore; {$ENDREGION 'Internal Declarations'} { Initializes an IBLFontData from a file specified by the given AFilename. The AReadFlags argument allows to specify flags that will be passed to IBLFileSystem.ReadFile to read the content of the file. It's possible to use memory mapping to get its content, which is the recommended way for reading system fonts. The best combination is to use the TBLFileReadFlag.MmapEnabled flag combined with TBLFileReadFlag.MmapAvoidSmall. This combination means to try to use memory mapping only when the size of the font is greater than a minimum value (determined by Blend2D), and would fallback to a regular open/read in case the memory mapping is not possible or failed for some other reason. Please note that not all files can be memory mapped so the TBLFileReadFlag.MmapNoFallback flag is not recommended. } procedure InitializeFromFile(const AFilename: String; const AReadFlags: TBLFileReadFlags = []); { Initializes an IBLFontData from the given AData. The given AData would be weak copied on success so the given array can be safely destroyed after the function returns. The weak copy of the passed AData is internal and there is no API to access it after the function returns. The reason for making it internal is that multiple implementations of IBLFontData may exist and some can only store data at table level, so Blend2D doesn't expose the detail about how the data is stored. } procedure InitializeFromData(const AData: TBytes); overload; { Creates IBLFontData from the given AData of the given ASize. AData must stay alive as long as this object is alive. Optionally an AOnDestroy event can be used as a notifier that will be called when the data is no longer needed. } procedure InitializeFromData(const AData: Pointer; const ASize: Integer; const AOnDestroy: TBLFontDataDestroyEvent = nil); overload; procedure Reset; function Equals(const AOther: IBLFontData): Boolean; function GetTags(const AFaceIndex: Integer): TArray; function QueryTable(const AFaceIndex: Integer; const ATag: TBLTag; out ATable: TBLFontTable): Integer; function QueryTables(const AFaceIndex: Integer; const ATags: TArray; out ATables: TArray): Integer; { Whether the font data is a built-in null instance. } property IsNone: Boolean read GetIsNone; { Tests whether the font data is empty (which the same as IsNone in this case). } property IsEmpty: Boolean read GetIsNone; { Type of font-face that this data describes. It doesn't matter if the content is a single font or a collection. In any case the FaceType would always return the type of the font-face that will be created by IBLFontFace.CreateFromData. } property FaceType: TBLFontFaceType read GetFaceType; { The number of faces of this font-data. If the data is not initialized the result would be always zero. If the data is initialized to a single font it would be 1, and if the data is initialized to a font collection then the return would correspond to the number of font-faces within that collection. You should not use FaceCount to check whether the font is a collection as it's possible to have a font-collection with just a single font. Using IsCollection is more reliable and would always return the right value. } property FaceCount: Integer read GetFaceCount; { Font-data flags } property Flags: TBLFontDataFlags read GetFlags; { Whether this font-data is a font-collection. } property IsCollection: Boolean read GetIsCollection; { Internal handle for use with the C API } property Handle: PBLFontDataCore read GetHandle; end; type { Implements IBLFontData } TBLFontData = class(TInterfacedObject, IBLFontData) {$REGION 'Internal Declarations'} private type TDestroyData = record FontData: IBLFontData; Event: TBLFontDataDestroyEvent; end; PDestroyData = ^TDestroyData; private FHandle: BLFontDataCore; FIsReference: Boolean; private class procedure DoDestroy(impl, destroyData: Pointer); cdecl; static; protected { IBLFontData } function GetIsNone: Boolean; function GetFaceType: TBLFontFaceType; function GetFaceCount: Integer; function GetFlags: TBLFontDataFlags; function GetIsCollection: Boolean; function GetHandle: PBLFontDataCore; procedure InitializeFromFile(const AFilename: String; const AReadFlags: TBLFileReadFlags = []); procedure InitializeFromData(const AData: TBytes); overload; procedure InitializeFromData(const AData: Pointer; const ASize: Integer; const AOnDestroy: TBLFontDataDestroyEvent = nil); overload; procedure Reset; function Equals(const AOther: IBLFontData): Boolean; reintroduce; overload; function GetTags(const AFaceIndex: Integer): TArray; function QueryTable(const AFaceIndex: Integer; const ATag: TBLTag; out ATable: TBLFontTable): Integer; function QueryTables(const AFaceIndex: Integer; const ATags: TArray; out ATables: TArray): Integer; private constructor Create(const AHandle: BLFontDataCore; const AIsReference: Boolean); overload; {$ENDREGION 'Internal Declarations'} public constructor Create; overload; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; { ============================================================================ [BLFontFace] ============================================================================ } type { Font face } IBLFontFace = interface ['{D51BEBAD-EB2A-41CA-B76C-5773E696CA80}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetWeight: TBLFontWeight; function GetStretch: TBLFontStretch; function GetStyle: TBLFontStyle; function GetFaceInfo: TBLFontFaceInfo; function GetFaceType: TBLFontFaceType; function GetOutlineType: TBLFontOutlineType; function GetFaceIndex: Integer; function GetFaceFlags: TBLFontFaceFlags; function GetHasTypographicNames: Boolean; function GetHasTypographicMetrics: Boolean; function GetHasCharToGlyphMapping: Boolean; function GetHasHorizontalMetrics: Boolean; function GetHasVerticalMetrics: Boolean; function GetHasHorizontalKerning: Boolean; function GetHasVerticalKerning: Boolean; function GetHasOpenTypeFeatures: Boolean; function GetHasPanoseData: Boolean; function GetHasUnicodeCoverage: Boolean; function GetHasBaselineYAt0: Boolean; function GetHasLSBPointXAt0: Boolean; function GetHasVariationSequences: Boolean; function GetHasOpenTypeVariations: Boolean; function GetIsSymbolFont: Boolean; function GetIsLastResortFont: Boolean; function GetDiagFlags: TBLFontFaceDiagFlags; function GetUniqueId: TBLUniqueId; function GetData: IBLFontData; function GetFullName: String; function GetFamilyName: String; function GetSubfamilyName: String; function GetPostScriptName: String; function GetDesignMetrics: TBLFontDesignMetrics; function GetUnitsPerEm: Integer; function GetPanose: TBLFontPanose; function GetUnicodeCoverage: TBLFontUnicodeCoverage; function GetHandle: PBLFontFaceCore; {$ENDREGION 'Internal Declarations'} { Initializes an IBLFontFace from a file specified by AFileName. This is a utility function that first creates a IBLFontData and then calls InitializeFromData(FontData, 0). See IBLFontData.CreateFromFile for more details, especially the use of AReadFlags is important for system fonts. This function offers a simplified creation of IBLFontFace directly from a file, but doesn't provide as much flexibility as InitializeFromData as it allows to specify a AFaceIndex, which can be used to load multiple font-faces from a TrueType/OpenType collection. The use of InitializeFromData is recommended for any serious font handling. } procedure InitializeFromFile(const AFilename: String; const AReadFlags: TBLFileReadFlags = []); { Initializes an IBLFontFace from IBLFontData at the given AFaceIndex. } procedure InitializeFromData(const AFontData: IBLFontData; const AFaceIndex: Integer); procedure Reset; function Equals(const AOther: IBLFontFace): Boolean; { Tests whether the font-face has a given AFlag set. } function HasFaceFlag(const AFlag: TBLFontFaceFlag): Boolean; { Whether the font face is a built-in null instance. } property IsNone: Boolean read GetIsNone; { Tests whether the font face is empty (which the same as IsNone in this case). } property IsEmpty: Boolean read GetIsNone; { Font weight (returns default weight in case this is a variable font). } property Weight: TBLFontWeight read GetWeight; { Font stretch (returns default weight in case this is a variable font). } property Stretch: TBLFontStretch read GetStretch; { Font style } property Style: TBLFontStyle read GetStyle; { Font-face information } property FaceInfo: TBLFontFaceInfo read GetFaceInfo; { Font-face type } property FaceType: TBLFontFaceType read GetFaceType; { Font-face outline type } property OutlineType: TBLFontOutlineType read GetOutlineType; { Zero-based index of this font-face. Face index does only make sense if this face is part of a TrueType or OpenType font collection. In that case the returned value would be the index of this face in that collection. If the face is not part of a collection then the returned value would always be zero. } property FaceIndex: Integer read GetFaceIndex; { Font-face flags } property FaceFlags: TBLFontFaceFlags read GetFaceFlags; { Tests whether the font-face uses typographic family and subfamily names. } property HasTypographicNames: Boolean read GetHasTypographicNames; { Tests whether the font-face uses typographic metrics. } property HasTypographicMetrics: Boolean read GetHasTypographicMetrics; { Tests whether the font-face provides character to glyph mapping. } property HasCharToGlyphMapping: Boolean read GetHasCharToGlyphMapping; { Tests whether the font-face has horizontal glyph metrics (advances, side bearings). } property HasHorizontalMetrics: Boolean read GetHasHorizontalMetrics; { Tests whether the font-face has vertical glyph metrics (advances, side bearings). } property HasVerticalMetrics: Boolean read GetHasVerticalMetrics; { Tests whether the font-face has a legacy horizontal kerning feature ('kern' table with horizontal kerning data). } property HasHorizontalKerning: Boolean read GetHasHorizontalKerning; { Tests whether the font-face has a legacy vertical kerning feature ('kern' table with vertical kerning data). } property HasVerticalKerning: Boolean read GetHasVerticalKerning; { Tests whether the font-face has OpenType features (GDEF, GPOS, GSUB). } property HasOpenTypeFeatures: Boolean read GetHasOpenTypeFeatures; { Tests whether the font-face has panose classification. } property HasPanoseData: Boolean read GetHasPanoseData; { Tests whether the font-face has unicode coverage information. } property HasUnicodeCoverage: Boolean read GetHasUnicodeCoverage; { Tests whether the font-face's baseline equals 0. } property HasBaselineYAt0: Boolean read GetHasBaselineYAt0; { Tests whether the font-face's left sidebearing point at `x` equals 0. } property HasLSBPointXAt0: Boolean read GetHasLSBPointXAt0; { Tests whether the font-face has unicode variation sequences feature. } property HasVariationSequences: Boolean read GetHasVariationSequences; { Tests whether the font-face has OpenType Font Variations feature. } property HasOpenTypeVariations: Boolean read GetHasOpenTypeVariations; { This is a symbol font. } property IsSymbolFont: Boolean read GetIsSymbolFont; { This is a last resort font. } property IsLastResortFont: Boolean read GetIsLastResortFont; { Font-face diagnostics flags } property DiagFlags: TBLFontFaceDiagFlags read GetDiagFlags; { A unique identifier describing this IBLFontFace. } property UniqueId: TBLUniqueId read GetUniqueId; { IBLFontData associated with this font-face. } property Data: IBLFontData read GetData; { Font full name } property FullName: String read GetFullName; { Family name } property FamilyName: String read GetFamilyName; { Font subfamily name } property SubfamilyName: String read GetSubfamilyName; { Font PostScript name } property PostScriptName: String read GetPostScriptName; { Design metrics of this IBLFontFace. } property DesignMetrics: TBLFontDesignMetrics read GetDesignMetrics; { Units per em, which are part of font's design metrics. } property UnitsPerEm: Integer read GetUnitsPerEm; { PANOSE classification of this IBLFontFace. } property Panose: TBLFontPanose read GetPanose; { Unicode coverage of this IBLFontFace. The returned unicode-coverage is not calculated by Blend2D so in general the value doesn't have to be correct. Use GetCharacterCoverage to get a coverage calculated by Blend2D at character granularity. } property UnicodeCoverage: TBLFontUnicodeCoverage read GetUnicodeCoverage; { Internal handle for use with the C API } property Handle: PBLFontFaceCore read GetHandle; end; type { Implements IBLFontFace } TBLFontFace = class(TInterfacedObject, IBLFontFace) {$REGION 'Internal Declarations'} private FHandle: BLFontFaceCore; FData: IBLFontData; FIsReference: Boolean; protected { IBLFontFace } function GetIsNone: Boolean; function GetWeight: TBLFontWeight; function GetStretch: TBLFontStretch; function GetStyle: TBLFontStyle; function GetFaceInfo: TBLFontFaceInfo; function GetFaceType: TBLFontFaceType; function GetOutlineType: TBLFontOutlineType; function GetFaceIndex: Integer; function GetFaceFlags: TBLFontFaceFlags; function GetHasTypographicNames: Boolean; function GetHasTypographicMetrics: Boolean; function GetHasCharToGlyphMapping: Boolean; function GetHasHorizontalMetrics: Boolean; function GetHasVerticalMetrics: Boolean; function GetHasHorizontalKerning: Boolean; function GetHasVerticalKerning: Boolean; function GetHasOpenTypeFeatures: Boolean; function GetHasPanoseData: Boolean; function GetHasUnicodeCoverage: Boolean; function GetHasBaselineYAt0: Boolean; function GetHasLSBPointXAt0: Boolean; function GetHasVariationSequences: Boolean; function GetHasOpenTypeVariations: Boolean; function GetIsSymbolFont: Boolean; function GetIsLastResortFont: Boolean; function GetDiagFlags: TBLFontFaceDiagFlags; function GetUniqueId: TBLUniqueId; function GetData: IBLFontData; function GetFullName: String; function GetFamilyName: String; function GetSubfamilyName: String; function GetPostScriptName: String; function GetDesignMetrics: TBLFontDesignMetrics; function GetUnitsPerEm: Integer; function GetPanose: TBLFontPanose; function GetUnicodeCoverage: TBLFontUnicodeCoverage; function GetHandle: PBLFontFaceCore; procedure InitializeFromFile(const AFilename: String; const AReadFlags: TBLFileReadFlags = []); procedure InitializeFromData(const AFontData: IBLFontData; const AFaceIndex: Integer); procedure Reset; function Equals(const AOther: IBLFontFace): Boolean; reintroduce; overload; function HasFaceFlag(const AFlag: TBLFontFaceFlag): Boolean; private constructor Create(const AHandle: BLFontFaceCore; const AIsReference: Boolean); overload; {$ENDREGION 'Internal Declarations'} public constructor Create; overload; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; { ============================================================================ [BLFont] ============================================================================ } type { Font } IBLFont = interface ['{47ED75E4-8E6C-4D0E-95D9-6321CD4F8694}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetFaceType: TBLFontFaceType; function GetFaceFlags: TBLFontFaceFlags; function GetSize: Single; function GetUnitsPerEm: Integer; function GetFace: IBLFontFace; function GetFeatures: TArray; function GetVariations: TArray; function GetWeight: TBLFontWeight; function GetStretch: TBLFontStretch; function GetStyle: TBLFontStyle; function GetMatrix: TBLFontMatrix; function GetMetrics: TBLFontMetrics; function GetMetricsPtr: PBLFontMetrics; function GetDesignMetrics: TBLFontDesignMetrics; function GetHandle: PBLFontCore; {$ENDREGION 'Internal Declarations'} procedure InitializeFromFace(const AFace: IBLFontFace; const ASize: Single); procedure Reset; function Equals(const AOther: IBLFont): Boolean; procedure Shape(const AGlyphBuffer: IBLGlyphBuffer); procedure MapTextToGlyphs(const AGlyphBuffer: IBLGlyphBuffer); overload; procedure MapTextToGlyphs(const AGlyphBuffer: IBLGlyphBuffer; out AState: TBLGlyphMappingState); overload; { TODO : Check when Blend2D updates APositioningFlags } procedure PositionGlyphs(const AGlyphBuffer: IBLGlyphBuffer; const APositioningFlags: Cardinal = $FFFFFFFF); procedure ApplyKerning(const AGlyphBuffer: IBLGlyphBuffer); procedure ApplyGSub(const AGlyphBuffer: IBLGlyphBuffer; const AIndex: Integer; const ALookups: TBLBitWord); procedure ApplyGPos(const AGlyphBuffer: IBLGlyphBuffer; const AIndex: Integer; const ALookups: TBLBitWord); function GetTextMetrics(const AGlyphBuffer: IBLGlyphBuffer): TBLTextMetrics; function GetGlyphBounds(const AGlyphData: PCardinal; const AGlyphAdvance, ACount: Integer): TArray; function GetGlyphAdvances(const AGlyphData: PCardinal; const AGlyphAdvance, ACount: Integer): TArray; function GetGlyphOutlines(const AGlyphId: Cardinal; const ASink: TBLPathSinkEvent): IBLPath; overload; function GetGlyphOutlines(const AGlyphId: Cardinal; const AUserMatrix: TBLMatrix2D; const ASink: TBLPathSinkEvent): IBLPath; overload; function GetGlyphRunOutlines(const AGlyphRun: TBLGlyphRun; const ASink: TBLPathSinkEvent): IBLPath; overload; function GetGlyphRunOutlines(const AGlyphRun: TBLGlyphRun; const AUserMatrix: TBLMatrix2D; const ASink: TBLPathSinkEvent): IBLPath; overload; { Whether the font is a built-in null instance. } property IsNone: Boolean read GetIsNone; { Tests whether the font is empty (which the same as IsNone in this case). } property IsEmpty: Boolean read GetIsNone; { Type of the font's associated font-face } property FaceType: TBLFontFaceType read GetFaceType; { Flags of the font } property FaceFlags: TBLFontFaceFlags read GetFaceFlags; { Size of the font } property Size: Single read GetSize; { The "units per em" (UPEM) of the font's associated font-face. } property UnitsPerEm: Integer read GetUnitsPerEm; { The font's associated font-face. Returns the same font-face, which was passed to InitializeFromFace. } property Face: IBLFontFace read GetFace; { The features associated with the font. } property Features: TArray read GetFeatures; { The variations associated with the font. } property Variations: TArray read GetVariations; { The weight of the font. } property Weight: TBLFontWeight read GetWeight; { The stretch of the font. } property Stretch: TBLFontStretch read GetStretch; { The style of the font. } property Style: TBLFontStyle read GetStyle; { The 2x2 matrix of the font. The returned TBLFontMatrix is used to scale fonts from design units into user units. The matrix usually has a negative M11 member as fonts use a different coordinate system than Blend2D. } property Matrix: TBLFontMatrix read GetMatrix; { The scaled metrics of the font. The returned metrics is a scale of design metrics that match the font size and its options. } property Metrics: TBLFontMetrics read GetMetrics; property MetricsPtr: PBLFontMetrics read GetMetricsPtr; { The design metrics of the font. The returned metrics is compatible with the metrics of IBLFontFace associated with this font. } property DesignMetrics: TBLFontDesignMetrics read GetDesignMetrics; { Internal handle for use with the C API } property Handle: PBLFontCore read GetHandle; end; type { Implements IBLFont } TBLFont = class(TInterfacedObject, IBLFont) {$REGION 'Internal Declarations'} private FHandle: BLFontCore; FFace: IBLFontFace; FSink: TBLPathSinkEvent; FSinkPath: IBLPath; private class function DoSink(path: PBLPathCore; info: Pointer; closure: Pointer): Cardinal; cdecl; static; protected { IBLFont } function GetIsNone: Boolean; function GetFaceType: TBLFontFaceType; function GetFaceFlags: TBLFontFaceFlags; function GetSize: Single; function GetUnitsPerEm: Integer; function GetFace: IBLFontFace; function GetFeatures: TArray; function GetVariations: TArray; function GetWeight: TBLFontWeight; function GetStretch: TBLFontStretch; function GetStyle: TBLFontStyle; function GetMatrix: TBLFontMatrix; function GetMetrics: TBLFontMetrics; function GetMetricsPtr: PBLFontMetrics; function GetDesignMetrics: TBLFontDesignMetrics; function GetHandle: PBLFontCore; procedure InitializeFromFace(const AFace: IBLFontFace; const ASize: Single); procedure Reset; function Equals(const AOther: IBLFont): Boolean; reintroduce; overload; procedure Shape(const AGlyphBuffer: IBLGlyphBuffer); procedure MapTextToGlyphs(const AGlyphBuffer: IBLGlyphBuffer); overload; procedure MapTextToGlyphs(const AGlyphBuffer: IBLGlyphBuffer; out AState: TBLGlyphMappingState); overload; procedure PositionGlyphs(const AGlyphBuffer: IBLGlyphBuffer; const APositioningFlags: Cardinal); procedure ApplyKerning(const AGlyphBuffer: IBLGlyphBuffer); procedure ApplyGSub(const AGlyphBuffer: IBLGlyphBuffer; const AIndex: Integer; const ALookups: TBLBitWord); procedure ApplyGPos(const AGlyphBuffer: IBLGlyphBuffer; const AIndex: Integer; const ALookups: TBLBitWord); function GetTextMetrics(const AGlyphBuffer: IBLGlyphBuffer): TBLTextMetrics; function GetGlyphBounds(const AGlyphData: PCardinal; const AGlyphAdvance, ACount: Integer): TArray; function GetGlyphAdvances(const AGlyphData: PCardinal; const AGlyphAdvance, ACount: Integer): TArray; function GetGlyphOutlines(const AGlyphId: Cardinal; const ASink: TBLPathSinkEvent): IBLPath; overload; function GetGlyphOutlines(const AGlyphId: Cardinal; const AUserMatrix: TBLMatrix2D; const ASink: TBLPathSinkEvent): IBLPath; overload; function GetGlyphRunOutlines(const AGlyphRun: TBLGlyphRun; const ASink: TBLPathSinkEvent): IBLPath; overload; function GetGlyphRunOutlines(const AGlyphRun: TBLGlyphRun; const AUserMatrix: TBLMatrix2D; const ASink: TBLPathSinkEvent): IBLPath; overload; {$ENDREGION 'Internal Declarations'} public constructor Create; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; {$ENDREGION 'Font'} {$REGION 'Font Manager'} { ============================================================================ [BLFontManager] ============================================================================ } type { Font data } IBLFontManager = interface ['{A75AAED4-30E3-4A65-978F-590528AB2DCF}'] {$REGION 'Internal Declarations'} function GetIsNone: Boolean; function GetFaceCount: Integer; function GetFamilyCount: Integer; function GetHandle: PBLFontManagerCore; {$ENDREGION 'Internal Declarations'} procedure Reset; function Equals(const AOther: IBLFontManager): Boolean; procedure Initialize; { Whether the font manager contains the given font AFace. } function HasFace(const AFace: IBLFontFace): Boolean; { Adds a font AFace to the font manager. Does nothing if the manager already contans the font face. Important conditions: * TBLResultCode.FontNotInitializes is raised if the font AFace is invalid. * TBLResultCode.OutOfMemory is raised if memory allocation failed. } procedure AddFace(const AFace: IBLFontFace); { Queries a font face by family name and returns the font face or nil if not found. } function QueryFace(const AName: String): IBLFontFace; overload; { Queries a font face by family name and returns the font face or nil if not found. The AProperties parameter contains query properties that the query engine will consider when doing the match. The best candidate will be selected based on the following rules: * Style has the highest priority. * Weight has the lowest priority. } function QueryFace(const AName: String; const AProperties: TBLFontQueryProperties): IBLFontFace; overload; { Queries all font-faces by family name and returns an array of font faces. } function QueryFacesByFamilyName(const AName: String): TArray; { Whether the font manager is a built-in null instance. } property IsNone: Boolean read GetIsNone; { The number of IBLFontFace instances the font manager holds. } property FaceCount: Integer read GetFaceCount; { The number of unique font families the font manager holds. } property FamilyCount: Integer read GetFamilyCount; { Internal handle for use with the C API } property Handle: PBLFontManagerCore read GetHandle; end; type { Implements IBLFontManager } TBLFontManager = class(TInterfacedObject, IBLFontManager) {$REGION 'Internal Declarations'} private FHandle: BLFontManagerCore; protected { IBLFontManager } function GetIsNone: Boolean; function GetFaceCount: Integer; function GetFamilyCount: Integer; function GetHandle: PBLFontManagerCore; procedure Reset; function Equals(const AOther: IBLFontManager): Boolean; reintroduce; overload; procedure Initialize; function HasFace(const AFace: IBLFontFace): Boolean; procedure AddFace(const AFace: IBLFontFace); function QueryFace(const AName: String): IBLFontFace; overload; function QueryFace(const AName: String; const AProperties: TBLFontQueryProperties): IBLFontFace; overload; function QueryFacesByFamilyName(const AName: String): TArray; {$ENDREGION 'Internal Declarations'} public constructor Create; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; {$ENDREGION 'Font Manager'} {$REGION 'Pixel Converter'} { ============================================================================ [BLPixelConverterCreateFlags] ============================================================================ } type { Flags used by IBLPixelConverter.Initialize. } TBLPixelConverterCreateFlag = ( { Specifies that the source palette in TBLFormatInfo doesn't have to be copied by IBLPixelConverter. The caller must ensure that the palette would stay valid until the pixel converter is destroyed. } DontCopyPalette = 0, { Specifies that the source palette in TBLFormatInfo is alterable and the pixel converter can modify it when preparing the conversion. The modification can be irreversible so only use this flag when you are sure that the palette passed to IBLPixelConverter.Initialize won't be needed outside of pixel conversion. The flag DontCopyPalette must be set as well, otherwise this flag would be ignored. } AlterablePalette = 1, { When there is no built-in conversion between the given pixel formats it's possible to use an intermediate format that is used during conversion. In such case the base pixel converter creates two more converters that are then used internally. This option disables such feature - creating a pixel converter would fail with TBLResultCode.NotImplemented error if direct conversion is not possible. } NoMultiStep = 2); TBLPixelConverterCreateFlags = set of TBLPixelConverterCreateFlag; { ============================================================================ [BLPixelConverter - Options] ============================================================================ } type { Pixel conversion options. } TBLPixelConverterOptions = record {$REGION 'Internal Declarations'} private FHandle: BLPixelConverterOptions; function GetOrigin: TBLPointI; inline; procedure SetOrigin(const AValue: TBLPointI); inline; function GetGap: Integer; inline; procedure SetGap(const AValue: Integer); inline; {$ENDREGION 'Internal Declarations'} public property Origin: TBLPointI read GetOrigin write SetOrigin; property Gap: Integer read GetGap write SetGap; end; PBLPixelConverterOptions = ^TBLPixelConverterOptions; { ============================================================================ [BLPixelConverter] ============================================================================ } type { Provides an interface to convert pixels between various pixel formats. The primary purpose of this class is to allow efficient conversion between pixel formats used natively by Blend2D and pixel formats used elsewhere, for example image codecs or native framebuffers. Note: A default-initialized converter has a valid conversion function that would return TBLResultCode.NotInitialized if invoked. Use IsInitialized to test whether the pixel converter was properly initialized. } IBLPixelConverter = interface ['{A75AAED4-30E3-4A65-978F-590528AB2DCF}'] {$REGION 'Internal Declarations'} function GetIsInitialized: Boolean; function GetHandle: PBLPixelConverterCore; {$ENDREGION 'Internal Declarations'} { Initializes a new pixel converter that will convert pixels described by ASrcInfo into pixels described by ADstInfo. Use ACreateFlags to further specify the parameters of the conversion. Note: Destination and source format information must be valid, otherwise a TBLResultCode.InvalidValue error is raised. } procedure Initialize(const ASrcInfo, ADstInfo: TBLFormatInfo; const ACreateFlags: TBLPixelConverterCreateFlags = []); procedure Reset; { Assigns the AOther pixel converter into this one. } procedure Assign(const AOther: IBLPixelConverter); { Converts a single span of pixels of AWidth. } procedure ConvertSpan(const ASrcData, ADstData: Pointer; const AWidth: Integer); overload; procedure ConvertSpan(const ASrcData, ADstData: Pointer; const AWidth: Integer; const AOptions: TBLPixelConverterOptions); overload; { Converts a rectangular area of pixels from source format to destination. } procedure ConvertRect(const ASrcData: Pointer; const ASrcStride: Integer; const ADstData: Pointer; const ADstStride, AWidth, AHeight: Integer); overload; procedure ConvertRect(const ASrcData: Pointer; const ASrcStride: Integer; const ADstData: Pointer; const ADstStride, AWidth, AHeight: Integer; const AOptions: TBLPixelConverterOptions); overload; { Returns True if the converter is initialized. } property IsInitialized: Boolean read GetIsInitialized; { Internal handle for use with the C API } property Handle: PBLPixelConverterCore read GetHandle; end; type { Implements IBLPixelConverter } TBLPixelConverter = class(TInterfacedObject, IBLPixelConverter) {$REGION 'Internal Declarations'} private FHandle: BLPixelConverterCore; protected { IBLPixelConverter } function GetIsInitialized: Boolean; function GetHandle: PBLPixelConverterCore; procedure Initialize(const ASrcInfo, ADstInfo: TBLFormatInfo; const ACreateFlags: TBLPixelConverterCreateFlags = []); procedure Reset; procedure Assign(const AOther: IBLPixelConverter); procedure ConvertSpan(const ASrcData, ADstData: Pointer; const AWidth: Integer); overload; procedure ConvertSpan(const ASrcData, ADstData: Pointer; const AWidth: Integer; const AOptions: TBLPixelConverterOptions); overload; procedure ConvertRect(const ASrcData: Pointer; const ASrcStride: Integer; const ADstData: Pointer; const ADstStride, AWidth, AHeight: Integer); overload; procedure ConvertRect(const ASrcData: Pointer; const ASrcStride: Integer; const ADstData: Pointer; const ADstStride, AWidth, AHeight: Integer; const AOptions: TBLPixelConverterOptions); overload; {$ENDREGION 'Internal Declarations'} public constructor Create; destructor Destroy; override; { Creates a pixel converter appropriate for the current platform. This is useful for platforms where the display format does not match the internal Blend2D format. For example, on macOS, iOS and Android, the red and blue color channels need to be swapped. On Windows, Blend2D's internal format matches the display format and no conversion is needed. On Windows, it returns a converter that doesn't convert, but just copies the data. However, it is more efficient to not use a pixel converter at all on Windows. On other platforms, it creates a converter that converts from PRGB to PBGR. } class function CreatePlatformConverter: IBLPixelConverter; static; end; {$ENDREGION 'Pixel Converter'} {$REGION 'Style'} { ============================================================================ [BLStyle - Enums] ============================================================================ } type { Style type. } TBLStyleType = ( { No style, nothing will be paint. } None = BL_STYLE_TYPE_NONE, { Solid color style. } Solid = BL_STYLE_TYPE_SOLID, { Pattern style. } Pattern = BL_STYLE_TYPE_PATTERN, { Gradient style. } Gradient = BL_STYLE_TYPE_GRADIENT); {$ENDREGION 'Style'} {$REGION 'Context'} { ============================================================================ [BLContext - Enums] ============================================================================ } type { Rendering context type. } TBLContextType = ( { No rendering context. } None = BL_CONTEXT_TYPE_NONE, { Dummy rendering context. } Dummy = BL_CONTEXT_TYPE_DUMMY, { Software-accelerated rendering context. } Raster = BL_CONTEXT_TYPE_RASTER); type { Rendering context hint. } TBLContextHint = ( { Rendering quality. } RenderingQuality = BL_CONTEXT_HINT_RENDERING_QUALITY, { Gradient quality. } GradientQuality = BL_CONTEXT_HINT_GRADIENT_QUALITY, { Pattern quality. } PatternQuality = BL_CONTEXT_HINT_PATTERN_QUALITY); type { Describes a rendering operation type - fill or stroke. The rendering context allows to get and set fill & stroke options directly or via "style" functions that take the rendering operation type (OpType) and dispatch the call to the right function. } TBLContextOpType = ( { Fill operation type. } Fill = BL_CONTEXT_OP_TYPE_FILL, { Stroke operation type. } Stroke = BL_CONTEXT_OP_TYPE_STROKE); type { Rendering context flush-flags, use with IBLContext.Flush. } TBLContextFlushFlag = ( _Dummy = 0, { Flush the command queue and wait for its completion (will block). } Sync = 31); TBLContextFlushFlags = set of TBLContextFlushFlag; type { Rendering context create-flags. } TBLContextCreateFlag = ( { Fallbacks to a synchronous rendering in case that the rendering engine wasn't able to acquire threads. This flag only makes sense when the asynchronous mode was specified by having TBLContextCreateInfo.ThreadCount greater than 0. If the rendering context fails to acquire at least one thread it would fallback to synchronous mode with no worker threads. Note: If this flag is specified with TBLContextCreateInfo.ThreadCount = 1 it means to immediately fallback to synchronous rendering. It's only practical to use this flag with 2 or more requested threads. } FallbackToSync = 3, { If this flag is specified and asynchronous rendering is enabled then the context would create its own isolated thread-pool, which is useful for debugging purposes. Do not use this flag in production as rendering contexts with isolated thread-pool have to create and destroy all threads they use. This flag is only useful for testing, debugging, and isolated benchmarking. } IsolatedThreadPool = 24, { If this flag is specified and JIT pipeline generation enabled then the rendering context would create its own isolated JIT runtime. which is useful for debugging purposes. This flag will be ignored if JIT pipeline generation is either not supported or was disabled by other flags. Do not use this flag in production as rendering contexts with isolated JIT runtime do not use global pipeline cache, that's it, after the rendering context is destroyed the JIT runtime is destroyed with it with all compiled pipelines. This flag is only useful for testing, debugging, and isolated benchmarking. } IsolatedJit = 25, { Override CPU features when creating isolated context. } OverrideCpuFeatures = 26); TBLContextCreateFlags = set of TBLContextCreateFlag; type { Specifies a rendering context property that can be specific to the rendering context implementation and that doesn't have its own C and C++ API. Different rendering context implementations may expose various properties that users can query to get more details about the rendering context itself, rendering details (like optimizations or possibly limitations), memory details, and other information that was collected during the rendering. Properties are never part of the rendering context state - they are stateless and are not subject to Save and Restore. Many properties are purely informative, but some not, e.g. AccumulatedErrorFlags. } TBLContextProperty = ( { Number of threads that the rendering context uses for rendering. } ThreadCount = BL_CONTEXT_PROPERTY_THREAD_COUNT, { Accumulated errors collected during the lifetime of the rendering context. } AccumulatedErrorFlags = BL_CONTEXT_PROPERTY_ACCUMULATED_ERROR_FLAGS); type { Error flags that are accumulated during the rendering context lifetime and that can be queried through TBLContext.QueryAccumulatedErrorFlags. The reason why these flags exist is that errors can happen during asynchronous rendering, and there is no way the user can catch these errors. } TBLContextErrorFlag = ( { The rendering context returned or encountered TBLResultCode.InvalidValue, which is mostly related to function argument handling. It's very likely some argument was wrong when calling TBLContext API. } InvalidValue = 0, { Invalid state describes something wrong, for example pipeline compilation problem. } InvalidState = 1, { The rendering context has encountered invalid geometry. } InvalidGeometry = 2, { The rendering context has encountered invalid glyph. } InvalidGlyph = 3, { The rendering context has encountered invalid or uninitialized font. } InvalidFont = 4, { Thread pool was exhausted and couldn't acquire the requested number of threads. } ThreadPoolExhausted = 29, { Out of memory condition. } OutOfMemory = 30, { Unknown error, which we don't have flag for. } UnknownError = 31); TBLContextErrorFlags = set of TBLContextErrorFlag; type { Clip mode. } TBLClipMode = ( { Clipping to a rectangle that is aligned to the pixel grid. } AlignedRect = BL_CLIP_MODE_ALIGNED_RECT, { Clipping to a rectangle that is not aligned to pixel grid. } UnalignedRect = BL_CLIP_MODE_UNALIGNED_RECT, { Clipping to a non-rectangular area that is defined by using mask. } Mask = BL_CLIP_MODE_MASK); type { Composition & blending operator. } TBLCompOp = ( { Source-over [default]. } SrcOver = BL_COMP_OP_SRC_OVER, { Source-copy. } SrcCopy = BL_COMP_OP_SRC_COPY, { Source-in. } SrcIn = BL_COMP_OP_SRC_IN, { Source-out. } SrcOut = BL_COMP_OP_SRC_OUT, { Source-atop. } SrcAtop = BL_COMP_OP_SRC_ATOP, { Destination-over. } DstOver = BL_COMP_OP_DST_OVER, { Destination-copy [nop]. } DstCopy = BL_COMP_OP_DST_COPY, { Destination-in. } DstIn = BL_COMP_OP_DST_IN, { Destination-out. } DstOut = BL_COMP_OP_DST_OUT, { Destination-atop. } DstAtop = BL_COMP_OP_DST_ATOP, { Xor. } ExclusiveOr = BL_COMP_OP_XOR, { Clear. } Clear = BL_COMP_OP_CLEAR, { Plus. } Plus = BL_COMP_OP_PLUS, { Minus. } Minus = BL_COMP_OP_MINUS, { Modulate. } Modulate = BL_COMP_OP_MODULATE, { Multiply. } Multiply = BL_COMP_OP_MULTIPLY, { Screen. } Screen = BL_COMP_OP_SCREEN, { Overlay. } Overlay = BL_COMP_OP_OVERLAY, { Darken. } Darken = BL_COMP_OP_DARKEN, { Lighten. } Lighten = BL_COMP_OP_LIGHTEN, { Color dodge. } ColorDodge = BL_COMP_OP_COLOR_DODGE, { Color burn. } ColorBurn = BL_COMP_OP_COLOR_BURN, { Linear burn. } LinearBurn = BL_COMP_OP_LINEAR_BURN, { Linear light. } LinearLight = BL_COMP_OP_LINEAR_LIGHT, { Pin light. } PinLight = BL_COMP_OP_PIN_LIGHT, { Hard-light. } HardLight = BL_COMP_OP_HARD_LIGHT, { Soft-light. } SoftLight = BL_COMP_OP_SOFT_LIGHT, { Difference. } Difference = BL_COMP_OP_DIFFERENCE, { Exclusion. } Exclusion = BL_COMP_OP_EXCLUSION); type { Gradient rendering quality. } TBLGradientQuality = ( { Nearest neighbor. } Nearest = BL_GRADIENT_QUALITY_NEAREST); type { Pattern quality. } TBLPatternQuality = ( { Nearest neighbor. } Nearest = BL_PATTERN_QUALITY_NEAREST, { Bilinear. } Bilinear = BL_PATTERN_QUALITY_BILINEAR); type { Rendering quality. } TBLRenderingQuality = ( { Render using anti-aliasing. } AntiAlias = BL_RENDERING_QUALITY_ANTIALIAS); { ============================================================================ [BLContext - CreateInfo] ============================================================================ } type { Information that can be used to customize the rendering context. } TBLContextCreateInfo = record {$REGION 'Internal Declarations'} private FHandle: BLContextCreateInfo; function GetFlags: TBLContextCreateFlags; inline; procedure SetFlags(const AValue: TBLContextCreateFlags); inline; {$ENDREGION 'Internal Declarations'} public procedure Reset; inline; { Create flags, see TBLContextCreateFlags. } property Flags: TBLContextCreateFlags read GetFlags write SetFlags; { Number of worker threads to use for asynchronous rendering, if non-zero. If ThreadCount is zero it means to initialize the context for synchronous rendering. This means that every operation will take effect immediately. If ThreadCount is 1 it means that the rendering will be asynchronous, but no thread would be acquired from a thread-pool, because the user thread will be used as a worker. And finally, if ThreadCount is greater than 1 then total of ThreadCount - 1 threads will be acquired from thread-pool and used as additional workers. } property ThreadCount: Integer read FHandle.threadCount write FHandle.threadCount; { CPU features to use in isolated JIT runtime (if supported), only used when Flags contains TBLContextCreateFlag.OverrideCpuFeatures. } property CpuFeatures: Cardinal read FHandle.cpuFeatures write FHandle.cpuFeatures; { Maximum number of commands to be queued. If this parameter is zero the queue size will be determined automatically. TODO: To be documented, has no effect at the moment. } property CommandQueueLimit: Integer read FHandle.commandQueueLimit write FHandle.commandQueueLimit; end; PBLContextCreateInfo = ^TBLContextCreateInfo; { ============================================================================ [BLContext - Cookie] ============================================================================ } type { Holds an arbitrary 128-bit value (cookie) that can be used to match other cookies. Blend2D uses cookies in places where it allows to "lock" some state that can only be unlocked by a matching cookie. Please don't confuse cookies with a security of any kind, it's just an arbitrary data that must match to proceed with a certain operation. Cookies can be used with IBLContext.Save and IBLContextRestore operations. } TBLContextCookie = record {$REGION 'Internal Declarations'} private FHandle: BLContextCookie; function GetIsEmpty: Boolean; inline; {$ENDREGION 'Internal Declarations'} public class operator Equal(const ALeft, ARight: TBLContextCookie): Boolean; inline; static; class operator NotEqual(const ALeft, ARight: TBLContextCookie): Boolean; inline; static; public procedure Reset; overload; inline; procedure Reset(const AOther: TBLContextCookie); overload; inline; procedure Reset(const AData0, AData1: UInt64); overload; inline; function Equals(const AOther: TBLContextCookie): Boolean; inline; property IsEmpty: Boolean read GetIsEmpty; end; PBLContextCookie = ^TBLContextCookie; { ============================================================================ [BLContext - Hints] ============================================================================ } type { Rendering context hints. } TBLContextHints = record {$REGION 'Internal Declarations'} private FHandle: BLContextHints; function GetGradientQuality: TBLGradientQuality; inline; function GetPatternQuality: TBLPatternQuality; inline; function GetRenderingQuality: TBLRenderingQuality; inline; procedure SetGradientQuality(const AValue: TBLGradientQuality); inline; procedure SetPatternQuality(const AValue: TBLPatternQuality); inline; procedure SetRenderingQuality(const AValue: TBLRenderingQuality); inline; {$ENDREGION 'Internal Declarations'} public property RenderingQuality: TBLRenderingQuality read GetRenderingQuality write SetRenderingQuality; property GradientQuality: TBLGradientQuality read GetGradientQuality write SetGradientQuality; property PatternQuality: TBLPatternQuality read GetPatternQuality write SetPatternQuality; end; PBLContextHints = ^TBLContextHints; { ============================================================================ [BLContext - State] ============================================================================ } type { Rendering context state. This state is not meant to be created by users, it's only provided for users that want to introspect the rendering context state. } TBLContextState = record {$REGION 'Internal Declarations'} private FHandle: BLContextState; function GetApproximationOptions: TBLApproximationOptions; inline; function GetCompOp: TBLCompOp; inline; function GetFillRule: TBLFillRule; inline; function GetFillStyle: TBLStyleType; overload; inline; function GetHints: TBLContextHints; inline; function GetMetaMatrix: TBLMatrix2D; inline; function GetSavedStateCount: Integer; inline; function GetStrokeOptions: TBLStrokeOptions; inline; function GetStrokeStyle: TBLStyleType; overload; inline; function GetTargetImage: IBLImage; inline; function GetTargetSize: TBLSize; inline; function GetUserMatrix: TBLMatrix2D; inline; function GetFillAlpha: Double; inline; function GetStrokeAlpha: Double; inline; {$ENDREGION 'Internal Declarations'} public { Target image or image object with nil impl in case that the rendering context doesn't render to an image. } property TargetImage: IBLImage read GetTargetImage; { Current size of the target in abstract units, pixels if rendering to IBLImage. } property TargetSize: TBLSize read GetTargetSize; { Current context hints. } property Hints: TBLContextHints read GetHints; { Current composition operator. } property CompOp: TBLCompOp read GetCompOp; { Current fill rule. } property FillRule: TBLFillRule read GetFillRule; { Current type of a style for fill operations. } property FillStyle: TBLStyleType read GetFillStyle; { Current type of a style for stroke operations. } property StrokeStyle: TBLStyleType read GetStrokeStyle; { Approximation options. } property ApproximationOptions: TBLApproximationOptions read GetApproximationOptions; { Current global alpha value [0, 1]. } property GlobalAlpha: Double read FHandle.globalAlpha; { Current fill alpha } property FillAlpha: Double read GetFillAlpha; { Current stroke alpha } property StrokeAlpha: Double read GetStrokeAlpha; { Current stroke options. } property StrokeOptions: TBLStrokeOptions read GetStrokeOptions; { Current meta transformation matrix. } property MetaMatrix: TBLMatrix2D read GetMetaMatrix; { Current user transformation matrix. } property UserMatrix: TBLMatrix2D read GetUserMatrix; { Count of saved states in the context. } property SavedStateCount: Integer read GetSavedStateCount; end; PBLContextState = ^TBLContextState; { ============================================================================ [BLContext] ============================================================================ } type { Rendering context } IBLContext = interface ['{079F0FF5-12D6-4D53-B5AA-79C1AEE83068}'] {$REGION 'Internal Declarations'} function GetTargetSize: TBLSize; function GetTargetWidth: Double; function GetTargetHeight: Double; function GetTargetImage: IBLImage; function GetContextType: TBLContextType; function GetIsNone: Boolean; function GetSavedStateCount: Integer; function GetMetaMatrix: TBLMatrix2D; function GetUserMatrix: TBLMatrix2D; procedure SetUserMatrix(const AValue: TBLMatrix2D); function GetHints: TBLContextHints; procedure SetHints(const AValue: TBLContextHints); function GetRenderingQuality: TBLRenderingQuality; procedure SetRenderingQuality(const AValue: TBLRenderingQuality); function GetGradientQuality: TBLGradientQuality; procedure SetGradientQuality(const AValue: TBLGradientQuality); function GetPatternQuality: TBLPatternQuality; procedure SetPatternQuality(const AValue: TBLPatternQuality); function GetApproximationOptions: TBLApproximationOptions; function GetFlattenMode: TBLFlattenMode; procedure SetFlattenMode(const AValue: TBLFlattenMode); function GetFlattenTolerance: Double; procedure SetFlattenTolerance(const AValue: Double); function GetCompOp: TBLCompOp; procedure SetCompOp(const AValue: TBLCompOp); function GetGlobalAlpha: Double; procedure SetGlobalAlpha(const AValue: Double); function GetFillStyle: TBLStyleType; overload; function GetStrokeStyle: TBLStyleType; overload; function GetFillAlpha: Double; procedure SetFillAlpha(const AValue: Double); function GetStrokeAlpha: Double; procedure SetStrokeAlpha(const AValue: Double); function GetFillColor: TBLRgba32; procedure SetFillColor(const AValue: TBLRgba32); function GetFillColor64: TBLRgba64; procedure SetFillColor64(const AValue: TBLRgba64); function GetFillColorF: TBLRgba; procedure SetFillColorF(const AValue: TBLRgba); function GetStrokeColor: TBLRgba32; procedure SetStrokeColor(const AValue: TBLRgba32); function GetStrokeColor64: TBLRgba64; procedure SetStrokeColor64(const AValue: TBLRgba64); function GetStrokeColorF: TBLRgba; procedure SetStrokeColorF(const AValue: TBLRgba); function GetFillPattern: IBLPattern; procedure SetFillPattern(const AValue: IBLPattern); function GetStrokePattern: IBLPattern; procedure SetStrokePattern(const AValue: IBLPattern); function GetFillGradient: IBLGradient; procedure SetFillGradient(const AValue: IBLGradient); function GetStrokeGradient: IBLGradient; procedure SetStrokeGradient(const AValue: IBLGradient); function GetFillRule: TBLFillRule; procedure SetFillRule(const AValue: TBLFillRule); function GetStrokeWidth: Double; procedure SetStrokeWidth(const AValue: Double); function GetStrokeMiterLimit: Double; procedure SetStrokeMiterLimit(const AValue: Double); function GetStrokeJoin: TBLStrokeJoin; procedure SetStrokeJoin(const AValue: TBLStrokeJoin); function GetStrokeStartCap: TBLStrokeCap; procedure SetStrokeStartCap(const AValue: TBLStrokeCap); function GetStrokeEndCap: TBLStrokeCap; procedure SetStrokeEndCap(const AValue: TBLStrokeCap); function GetStrokeDashOffset: Double; procedure SetStrokeDashOffset(const AValue: Double); function GetStrokeDashArray: TArray; procedure SetStrokeDashArray(const AValue: TArray); function GetStrokeTransformOrder: TBLStrokeTransformOrder; procedure SetStrokeTransformOrder(const AValue: TBLStrokeTransformOrder); function GetStrokeOptions: TBLStrokeOptions; procedure SetStrokeOptions(const AValue: TBLStrokeOptions); function GetHandle: PBLContextCore; {$ENDREGION 'Internal Declarations'} { Resets this rendering context to the default constructed one. Similar behavior to the destructor, but the context will still be valid after Reset and would behave like a default constructed context. } procedure Reset; { Whether this and AOther point to the same rendering context. } function Equals(const AOther: IBLContext): Boolean; overload; { Starts rendering to the given AImage. If this operation succeeds then the rendering context will have exclusive access to the image data. This means that no other renderer can use it during rendering. } procedure Start(const AImage: IBLImage); overload; procedure Start(const AImage: IBLImage; const ACreateInfo: TBLContextCreateInfo); overload; { Waits for completion of all render commands and detaches the rendering context from the rendering target. After Finish completes the rendering context implementation would be released and replaced by a built-in null instance (no context). } procedure Finish; { Flushes the context } procedure Flush(const AFlags: TBLContextFlushFlags); { Queries the number of threads that the rendering context uses. If the returned value is zero it means that the rendering is synchronous, otherwise it describes the number of threads used for asynchronous rendering which include the user thread. For example if the returned value is 2 it means that the rendering context uses the user thread and one more worker. } function QueryThreadCount: Integer; { Queries accumulated errors as flags. Errors may accumulate during the lifetime of the rendering context. } function QueryAccumulatedErrorFlags: TBLContextErrorFlags; { Saves the current rendering context state. Blend2D uses optimizations that make Save a cheap operation. Only core values are actually saved in Save, others will only be saved if they are modified. This means that consecutive calls to Save and Restore do almost nothing. } procedure Save; overload; { Saves the current rendering context state and creates a restoration ACookie. If you use a ACookie to save a state you have to use the same cookie to restore it otherwise the Restore would fail. Please note that cookies are not a means of security, they are provided for making it easier to guarantee that a code that you may not control won't break your context. } procedure Save(out ACookie: TBLContextCookie); overload; { Restores the top-most saved context-state. Possible errors: * TBLResultCode.NoStatesToRestore: There are no saved states to restore. * TBLResultCode.NoMatchingCookie: Previous state was saved with cookie, which was not provided. You would need the correct cookie to restore such state. } procedure Restore; overload; { Restores to the point that matches the given ACookie. More than one state can be restored in case that the ACookie points to some previous state in the list. Possible errors: * TBLResultCode.NoStatesToRestore: There are no saved states to restore. * TBLResultCode.NoMatchingCookie: The cookie did't match any saved state. } procedure Restore(const ACookie: TBLContextCookie); overload; { Resets user matrix to identity. } procedure ResetMatrix; procedure Translate(const AX, AY: Double); overload; procedure Translate(const APoint: TBLPointI); overload; procedure Translate(const APoint: TBLPoint); overload; procedure Scale(const AXY: Double); overload; procedure Scale(const AX, AY: Double); overload; procedure Scale(const APoint: TBLPointI); overload; procedure Scale(const APoint: TBLPoint); overload; procedure Skew(const AX, AY: Double); overload; procedure Skew(const APoint: TBLPoint); overload; procedure Rotate(const AAngle: Double); overload; procedure Rotate(const AAngle, AX, AY: Double); overload; procedure Rotate(const AAngle: Double; const APoint: TBLPointI); overload; procedure Rotate(const AAngle: Double; const APoint: TBLPoint); overload; procedure Transform(const AMatrix: TBLMatrix2D); procedure PostTranslate(const AX, AY: Double); overload; procedure PostTranslate(const APoint: TBLPointI); overload; procedure PostTranslate(const APoint: TBLPoint); overload; procedure PostScale(const AXY: Double); overload; procedure PostScale(const AX, AY: Double); overload; procedure PostScale(const APoint: TBLPointI); overload; procedure PostScale(const APoint: TBLPoint); overload; procedure PostSkew(const AX, AY: Double); overload; procedure PostSkew(const APoint: TBLPoint); overload; procedure PostRotate(const AAngle: Double); overload; procedure PostRotate(const AAngle, AX, AY: Double); overload; procedure PostRotate(const AAngle: Double; const APoint: TBLPointI); overload; procedure PostRotate(const AAngle: Double; const APoint: TBLPoint); overload; procedure PostTransform(const AMatrix: TBLMatrix2D); { Store the result of combining the current MetaMatrix and UserMatrix to MetaMatrix and reset UserMatrix to identity. Please note that this operation is irreversible. The only way to restore both matrices to the state before the call to UserToMeta is to use Save and Restore functions. } procedure UserToMeta; { These are alternatives to the FillColor, FillColor64, FillPattern and FillGradient properties. } procedure GetFillStyle(out ARgba: TBLRgba32); overload; procedure GetFillStyle(out ARgba: TBLRgba64); overload; procedure GetFillStyle(out ARgba: TBLRgba); overload; procedure GetFillStyle(out APattern: IBLPattern); overload; procedure GetFillStyle(out AGradient: IBLGradient); overload; procedure SetFillStyle(const ARgba: TBLRgba32); overload; procedure SetFillStyle(const ARgba: TBLRgba64); overload; procedure SetFillStyle(const ARgba: TBLRgba); overload; procedure SetFillStyle(const APattern: IBLPattern); overload; procedure SetFillStyle(const AGradient: IBLGradient); overload; procedure SetFillStyle(const AImage: IBLImage); overload; { These are alternatives to the StrokeColor, StrokeColor64, StrokePattern and StrokeGradient properties. } procedure GetStrokeStyle(out ARgba: TBLRgba32); overload; procedure GetStrokeStyle(out ARgba: TBLRgba64); overload; procedure GetStrokeStyle(out ARgba: TBLRgba); overload; procedure GetStrokeStyle(out APattern: IBLPattern); overload; procedure GetStrokeStyle(out AGradient: IBLGradient); overload; procedure SetStrokeStyle(const ARgba: TBLRgba32); overload; procedure SetStrokeStyle(const ARgba: TBLRgba64); overload; procedure SetStrokeStyle(const ARgba: TBLRgba); overload; procedure SetStrokeStyle(const APattern: IBLPattern); overload; procedure SetStrokeStyle(const AGradient: IBLGradient); overload; procedure SetStrokeStyle(const AImage: IBLImage); overload; { Restores clipping to the last saved state or to the context default clipping if there is no saved state. If there are no saved states then it resets clipping completely to the initial state that was used when the rendering context was created. } procedure RestoreClipping; procedure ClipToRect(const ARect: TBLRectI); overload; procedure ClipToRect(const ARect: TBLRect); overload; procedure ClipToRect(const AX, AY, AW, AH: Double); overload; { Clear everything. } procedure ClearAll; { Clears a rectangle ARect. } procedure ClearRect(const ARect: TBLRectI); overload; procedure ClearRect(const ARect: TBLRect); overload; procedure ClearRect(const AX, AY, AW, AH: Double); overload; { Fills everything. } procedure FillAll; { Fills a box. } procedure FillBox(const ABox: TBLBoxI); overload; procedure FillBox(const ABox: TBLBox); overload; procedure FillBox(const AX0, AY0, AX1, AY1: Double); overload; { Fills a rectangle ARect. } procedure FillRect(const ARect: TBLRectI); overload; procedure FillRect(const ARect: TBLRect); overload; procedure FillRect(const AX, AY, AW, AH: Double); overload; { Fills a circle. } procedure FillCircle(const ACircle: TBLCircle); overload; procedure FillCircle(const ACX, ACY, AR: Double); overload; { Fills an ellipse. } procedure FillEllipse(const AEllipse: TBLEllipse); overload; procedure FillEllipse(const ACX, ACY, ARX, ARY: Double); overload; { Fills a rounded rectangle. } procedure FillRoundRect(const ARoundRect: TBLRoundRect); overload; procedure FillRoundRect(const ARect: TBLRect; const AR: Double); overload; procedure FillRoundRect(const ARect: TBLRect; const ARX, ARY: Double); overload; procedure FillRoundRect(const AX, AY, AW, AH, AR: Double); overload; procedure FillRoundRect(const AX, AY, AW, AH, ARX, ARY: Double); overload; { Fills a chord. } procedure FillChord(const AChord: TBLArc); overload; procedure FillChord(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure FillChord(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; { Fills a pie. } procedure FillPie(const APie: TBLArc); overload; procedure FillPie(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure FillPie(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; { Fills a triangle. } procedure FillTriangle(const ATriangle: TBLTriangle); overload; procedure FillTriangle(const AX0, AY0, AX1, AY1, AX2, AY2: Double); overload; { Fills a polygon. } procedure FillPolygon(const APoly: TArray); overload; procedure FillPolygon(const APoly: TBLArrayView); overload; procedure FillPolygon(const APoly: PBLPoint; const ACount: Integer); overload; procedure FillPolygon(const APoly: TArray); overload; procedure FillPolygon(const APoly: TBLArrayView); overload; procedure FillPolygon(const APoly: PBLPointI; const ACount: Integer); overload; { Fills an array of boxes. } procedure FillBoxArray(const ABoxes: TArray); overload; procedure FillBoxArray(const ABoxes: TBLArrayView); overload; procedure FillBoxArray(const ABoxes: PBLBox; const ACount: Integer); overload; procedure FillBoxArray(const ABoxes: TArray); overload; procedure FillBoxArray(const ABoxes: TBLArrayView); overload; procedure FillBoxArray(const ABoxes: PBLBoxI; const ACount: Integer); overload; { Fills an array of rectangles. } procedure FillRectArray(const ARects: TArray); overload; procedure FillRectArray(const ARects: TBLArrayView); overload; procedure FillRectArray(const ARects: PBLRect; const ACount: Integer); overload; procedure FillRectArray(const ARects: TArray); overload; procedure FillRectArray(const ARects: TBLArrayView); overload; procedure FillRectArray(const ARects: PBLRectI; const ACount: Integer); overload; { Fills the given ARegion. } procedure FillRegion(const ARegion: IBLRegion); { Fills the given Path. } procedure FillPath(const APath: IBLPath); { Fills the passed text by using the given AFont. } procedure FillText(const ADst: TBLPointI; const AFont: IBLFont; const AText: String); overload; procedure FillText(const ADst: TBLPoint; const AFont: IBLFont; const AText: String); overload; procedure FillText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UTF8String); overload; procedure FillText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UTF8String); overload; procedure FillText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UCS4String); overload; procedure FillText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UCS4String); overload; { Fills the passed AGlyphRun by using the given AFont. } procedure FillGlyphRun(const ADst: TBLPointI; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); overload; procedure FillGlyphRun(const ADst: TBLPoint; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); overload; procedure FillGlyphRun(const ADst: TBLPointI; const AFont: IBLFont; const AGlyphRun: PBLGlyphRun); overload; procedure FillGlyphRun(const ADst: TBLPoint; const AFont: IBLFont; const AGlyphRun: PBLGlyphRun); overload; { Strokes a box. } procedure StrokeBox(const ABox: TBLBoxI); overload; procedure StrokeBox(const ABox: TBLBox); overload; procedure StrokeBox(const AX0, AY0, AX1, AY1: Double); overload; { Strokes a rectangle. } procedure StrokeRect(const ARect: TBLRectI); overload; procedure StrokeRect(const ARect: TBLRect); overload; procedure StrokeRect(const AX, AY, AW, AH: Double); overload; { Strokes a line. } procedure StrokeLine(const ALine: TBLLine); overload; procedure StrokeLine(const AP0, AP1: TBLPoint); overload; procedure StrokeLine(const AX0, AY0, AX1, AY1: Double); overload; { Strokes a circle. } procedure StrokeCircle(const ACircle: TBLCircle); overload; procedure StrokeCircle(const ACX, ACY, AR: Double); overload; { Strokes an ellipse. } procedure StrokeEllipse(const AEllipse: TBLEllipse); overload; procedure StrokeEllipse(const ACX, ACY, ARX, ARY: Double); overload; { Strokes a rounded rectangle. } procedure StrokeRoundRect(const ARoundRect: TBLRoundRect); overload; procedure StrokeRoundRect(const ARect: TBLRect; const AR: Double); overload; procedure StrokeRoundRect(const ARect: TBLRect; const ARX, ARY: Double); overload; procedure StrokeRoundRect(const AX, AY, AW, AH, AR: Double); overload; procedure StrokeRoundRect(const AX, AY, AW, AH, ARX, ARY: Double); overload; { Strokes an arc. } procedure StrokeArc(const AArc: TBLArc); overload; procedure StrokeArc(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure StrokeArc(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; { Strokes a chord. } procedure StrokeChord(const AChord: TBLArc); overload; procedure StrokeChord(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure StrokeChord(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; { Strokes a pie. } procedure StrokePie(const APie: TBLArc); overload; procedure StrokePie(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure StrokePie(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; { Strokes a triangle. } procedure StrokeTriangle(const ATriangle: TBLTriangle); overload; procedure StrokeTriangle(const AX0, AY0, AX1, AY1, AX2, AY2: Double); overload; { Strokes a polyline. } procedure StrokePolyline(const APoly: TArray); overload; procedure StrokePolyline(const APoly: TBLArrayView); overload; procedure StrokePolyline(const APoly: PBLPoint; const ACount: Integer); overload; procedure StrokePolyline(const APoly: TArray); overload; procedure StrokePolyline(const APoly: TBLArrayView); overload; procedure StrokePolyline(const APoly: PBLPointI; const ACount: Integer); overload; { Strokes a polygon. } procedure StrokePolygon(const APoly: TArray); overload; procedure StrokePolygon(const APoly: TBLArrayView); overload; procedure StrokePolygon(const APoly: PBLPoint; const ACount: Integer); overload; procedure StrokePolygon(const APoly: TArray); overload; procedure StrokePolygon(const APoly: TBLArrayView); overload; procedure StrokePolygon(const APoly: PBLPointI; const ACount: Integer); overload; { Strokes an array of boxes. } procedure StrokeBoxArray(const ABoxes: TArray); overload; procedure StrokeBoxArray(const ABoxes: TBLArrayView); overload; procedure StrokeBoxArray(const ABoxes: PBLBox; const ACount: Integer); overload; procedure StrokeBoxArray(const ABoxes: TArray); overload; procedure StrokeBoxArray(const ABoxes: TBLArrayView); overload; procedure StrokeBoxArray(const ABoxes: PBLBoxI; const ACount: Integer); overload; { Strokes an array of rectangles. } procedure StrokeRectArray(const ARects: TArray); overload; procedure StrokeRectArray(const ARects: TBLArrayView); overload; procedure StrokeRectArray(const ARects: PBLRect; const ACount: Integer); overload; procedure StrokeRectArray(const ARects: TArray); overload; procedure StrokeRectArray(const ARects: TBLArrayView); overload; procedure StrokeRectArray(const ARects: PBLRectI; const ACount: Integer); overload; { Strokes the given Path. } procedure StrokePath(const APath: IBLPath); { Strokes the passed text by using the given AFont. } procedure StrokeText(const ADst: TBLPointI; const AFont: IBLFont; const AText: String); overload; procedure StrokeText(const ADst: TBLPoint; const AFont: IBLFont; const AText: String); overload; procedure StrokeText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UTF8String); overload; procedure StrokeText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UTF8String); overload; procedure StrokeText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UCS4String); overload; procedure StrokeText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UCS4String); overload; { Strokes the passed AGlyphRun by using the given AFont. } procedure StrokeGlyphRun(const ADst: TBLPointI; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); overload; procedure StrokeGlyphRun(const ADst: TBLPoint; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); overload; { Blits source image ASrc at coordinates specified by ADst. } procedure BlitImage(const ADst: TBLPoint; const ASrc: IBLImage); overload; procedure BlitImage(const ADst: TBLPointI; const ASrc: IBLImage); overload; { Blits an area of source image ASrc specified by ASrcArea at coordinates specified by ADst.} procedure BlitImage(const ADst: TBLPoint; const ASrc: IBLImage; const ASrcArea: TBLRectI); overload; procedure BlitImage(const ADst: TBLPointI; const ASrc: IBLImage; const ASrcArea: TBLRectI); overload; { Blits a source image ASrc scaled to fit into ADst rectangle. } procedure BlitImage(const ADst: TBLRect; const ASrc: IBLImage); overload; procedure BlitImage(const ADst: TBLRectI; const ASrc: IBLImage); overload; { Blits an area of source image ASrc specified by ASrcArea scaled to fit into ADst rectangle. } procedure BlitImage(const ADst: TBLRect; const ASrc: IBLImage; const ASrcArea: TBLRectI); overload; procedure BlitImage(const ADst: TBLRectI; const ASrc: IBLImage; const ASrcArea: TBLRectI); overload; { Target size in abstract units (pixels in case of IBLImage) } property TargetSize: TBLSize read GetTargetSize; { Target width in abstract units (pixels in case of IBLImage) } property TargetWidth: Double read GetTargetWidth; { Target width in abstract units (pixels in case of IBLImage) } property TargetHeight: Double read GetTargetHeight; { Returns the target image or nil if there is no target image. Note: The rendering context doesn't own the image, but it increases its writer count, which means that the image will not be destroyed even when user destroys it during the rendering (in such case it will be destroyed after the rendering ends when the writer count goes to zero). This means that the rendering context must hold the image and not the pointer to the IBLImage passed to either the constructor or Start function. So the returned pointer is not the same as the pointer passed to Start, but it points to the same impl. } property TargetImage: IBLImage read GetTargetImage; { The type of this context } property ContextType: TBLContextType read GetContextType; { Whether the context is a built-in null instance. } property IsNone: Boolean read GetIsNone; { The number of saved states in the context (0 means no saved states). } property SavedStateCount: Integer read GetSavedStateCount; { Meta-matrix. Meta matrix is a core transformation matrix that is normally not changed by transformations applied to the context. Instead it acts as a secondary matrix used to create the final transformation matrix from meta and user matrices. Meta matrix can be used to scale the whole context for HI-DPI rendering or to change the orientation of the image being rendered, however, the number of use-cases is unlimited. To change the meta-matrix you must first change user-matrix and then call UserToMeta, which would update meta-matrix and clear user-matrix. See UserMatrix and UserToMeta. } property MetaMatrix: TBLMatrix2D read GetMetaMatrix; { User-matrix. User matrix contains all transformations that happened to the rendering context unless the context was restored or UserToMeta was called. } property UserMatrix: TBLMatrix2D read GetUserMatrix write SetUserMatrix; { Rendering hints. } property Hints: TBLContextHints read GetHints write SetHints; property RenderingQuality: TBLRenderingQuality read GetRenderingQuality write SetRenderingQuality; property GradientQuality: TBLGradientQuality read GetGradientQuality write SetGradientQuality; property PatternQuality: TBLPatternQuality read GetPatternQuality write SetPatternQuality; { Approximation options. } property ApproximationOptions: TBLApproximationOptions read GetApproximationOptions; { Flatten mode. } property FlattenMode: TBLFlattenMode read GetFlattenMode write SetFlattenMode; { Tolerance used for curve flattening. } property FlattenTolerance: Double read GetFlattenTolerance write SetFlattenTolerance; { Composition operator. } property CompOp: TBLCompOp read GetCompOp write SetCompOp; { Global alpha value. } property GlobalAlpha: Double read GetGlobalAlpha write SetGlobalAlpha; { Fill style } property FillStyle: TBLStyleType read GetFillStyle; { Stroke style } property StrokeStyle: TBLStyleType read GetStrokeStyle; { Fill alpha } property FillAlpha: Double read GetFillAlpha write SetFillAlpha; { Stroke alpha } property StrokeAlpha: Double read GetStrokeAlpha write SetStrokeAlpha; { Fill color } property FillColor: TBLRgba32 read GetFillColor write SetFillColor; property FillColor64: TBLRgba64 read GetFillColor64 write SetFillColor64; property FillColorF: TBLRgba read GetFillColorF write SetFillColorF; { Stroke color } property StrokeColor: TBLRgba32 read GetStrokeColor write SetStrokeColor; property StrokeColor64: TBLRgba64 read GetStrokeColor64 write SetStrokeColor64; property StrokeColorF: TBLRgba read GetStrokeColorF write SetStrokeColorF; { Fill Pattern } property FillPattern: IBLPattern read GetFillPattern write SetFillPattern; { Stroke Pattern } property StrokePattern: IBLPattern read GetStrokePattern write SetStrokePattern; { Fill Gradient } property FillGradient: IBLGradient read GetFillGradient write SetFillGradient; { Stroke Gradient } property StrokeGradient: IBLGradient read GetStrokeGradient write SetStrokeGradient; { Fill rule } property FillRule: TBLFillRule read GetFillRule write SetFillRule; { Stroke width } property StrokeWidth: Double read GetStrokeWidth write SetStrokeWidth; { Stroke miter-limit. } property StrokeMiterLimit: Double read GetStrokeMiterLimit write SetStrokeMiterLimit; { Stroke join } property StrokeJoin: TBLStrokeJoin read GetStrokeJoin write SetStrokeJoin; { Stroke start-cap } property StrokeStartCap: TBLStrokeCap read GetStrokeStartCap write SetStrokeStartCap; { Stroke end-cap } property StrokeEndCap: TBLStrokeCap read GetStrokeEndCap write SetStrokeEndCap; { Stroke dash-offset. } property StrokeDashOffset: Double read GetStrokeDashOffset write SetStrokeDashOffset; { Stroke dash-array. } property StrokeDashArray: TArray read GetStrokeDashArray write SetStrokeDashArray; { Stroke transform order } property StrokeTransformOrder: TBLStrokeTransformOrder read GetStrokeTransformOrder write SetStrokeTransformOrder; { All stroke options } property StrokeOptions: TBLStrokeOptions read GetStrokeOptions write SetStrokeOptions; { Internal handle for use with the C API } property Handle: PBLContextCore read GetHandle; end; type { Implements IBLContext } TBLContext = class(TInterfacedObject, IBLContext) {$REGION 'Internal Declarations'} private FHandle: BLContextCore; protected { IBLContext } function GetTargetSize: TBLSize; function GetTargetWidth: Double; function GetTargetHeight: Double; function GetTargetImage: IBLImage; function GetContextType: TBLContextType; function GetIsNone: Boolean; function GetSavedStateCount: Integer; function GetMetaMatrix: TBLMatrix2D; function GetUserMatrix: TBLMatrix2D; procedure SetUserMatrix(const AValue: TBLMatrix2D); function GetHints: TBLContextHints; procedure SetHints(const AValue: TBLContextHints); function GetRenderingQuality: TBLRenderingQuality; procedure SetRenderingQuality(const AValue: TBLRenderingQuality); function GetGradientQuality: TBLGradientQuality; procedure SetGradientQuality(const AValue: TBLGradientQuality); function GetPatternQuality: TBLPatternQuality; procedure SetPatternQuality(const AValue: TBLPatternQuality); function GetApproximationOptions: TBLApproximationOptions; function GetFlattenMode: TBLFlattenMode; procedure SetFlattenMode(const AValue: TBLFlattenMode); function GetFlattenTolerance: Double; procedure SetFlattenTolerance(const AValue: Double); function GetCompOp: TBLCompOp; procedure SetCompOp(const AValue: TBLCompOp); function GetGlobalAlpha: Double; procedure SetGlobalAlpha(const AValue: Double); function GetFillStyle: TBLStyleType; overload; function GetStrokeStyle: TBLStyleType; overload; function GetFillAlpha: Double; procedure SetFillAlpha(const AValue: Double); function GetStrokeAlpha: Double; procedure SetStrokeAlpha(const AValue: Double); function GetFillColor: TBLRgba32; procedure SetFillColor(const AValue: TBLRgba32); function GetFillColor64: TBLRgba64; procedure SetFillColor64(const AValue: TBLRgba64); function GetFillColorF: TBLRgba; procedure SetFillColorF(const AValue: TBLRgba); function GetStrokeColor: TBLRgba32; procedure SetStrokeColor(const AValue: TBLRgba32); function GetStrokeColor64: TBLRgba64; procedure SetStrokeColor64(const AValue: TBLRgba64); function GetStrokeColorF: TBLRgba; procedure SetStrokeColorF(const AValue: TBLRgba); function GetFillPattern: IBLPattern; procedure SetFillPattern(const AValue: IBLPattern); function GetStrokePattern: IBLPattern; procedure SetStrokePattern(const AValue: IBLPattern); function GetFillGradient: IBLGradient; procedure SetFillGradient(const AValue: IBLGradient); function GetStrokeGradient: IBLGradient; procedure SetStrokeGradient(const AValue: IBLGradient); function GetFillRule: TBLFillRule; procedure SetFillRule(const AValue: TBLFillRule); function GetStrokeWidth: Double; procedure SetStrokeWidth(const AValue: Double); function GetStrokeMiterLimit: Double; procedure SetStrokeMiterLimit(const AValue: Double); function GetStrokeJoin: TBLStrokeJoin; procedure SetStrokeJoin(const AValue: TBLStrokeJoin); function GetStrokeStartCap: TBLStrokeCap; procedure SetStrokeStartCap(const AValue: TBLStrokeCap); function GetStrokeEndCap: TBLStrokeCap; procedure SetStrokeEndCap(const AValue: TBLStrokeCap); function GetStrokeDashOffset: Double; procedure SetStrokeDashOffset(const AValue: Double); function GetStrokeDashArray: TArray; procedure SetStrokeDashArray(const AValue: TArray); function GetStrokeTransformOrder: TBLStrokeTransformOrder; procedure SetStrokeTransformOrder(const AValue: TBLStrokeTransformOrder); function GetStrokeOptions: TBLStrokeOptions; procedure SetStrokeOptions(const AValue: TBLStrokeOptions); function GetHandle: PBLContextCore; procedure Reset; function Equals(const AOther: IBLContext): Boolean; reintroduce; overload; procedure Start(const AImage: IBLImage); overload; procedure Start(const AImage: IBLImage; const ACreateInfo: TBLContextCreateInfo); overload; procedure Finish; procedure Flush(const AFlags: TBLContextFlushFlags); function QueryThreadCount: Integer; function QueryAccumulatedErrorFlags: TBLContextErrorFlags; procedure Save; overload; procedure Save(out ACookie: TBLContextCookie); overload; procedure Restore; overload; procedure Restore(const ACookie: TBLContextCookie); overload; procedure ResetMatrix; procedure Translate(const AX, AY: Double); overload; procedure Translate(const APoint: TBLPointI); overload; procedure Translate(const APoint: TBLPoint); overload; procedure Scale(const AXY: Double); overload; procedure Scale(const AX, AY: Double); overload; procedure Scale(const APoint: TBLPointI); overload; procedure Scale(const APoint: TBLPoint); overload; procedure Skew(const AX, AY: Double); overload; procedure Skew(const APoint: TBLPoint); overload; procedure Rotate(const AAngle: Double); overload; procedure Rotate(const AAngle, AX, AY: Double); overload; procedure Rotate(const AAngle: Double; const APoint: TBLPointI); overload; procedure Rotate(const AAngle: Double; const APoint: TBLPoint); overload; procedure Transform(const AMatrix: TBLMatrix2D); procedure PostTranslate(const AX, AY: Double); overload; procedure PostTranslate(const APoint: TBLPointI); overload; procedure PostTranslate(const APoint: TBLPoint); overload; procedure PostScale(const AXY: Double); overload; procedure PostScale(const AX, AY: Double); overload; procedure PostScale(const APoint: TBLPointI); overload; procedure PostScale(const APoint: TBLPoint); overload; procedure PostSkew(const AX, AY: Double); overload; procedure PostSkew(const APoint: TBLPoint); overload; procedure PostRotate(const AAngle: Double); overload; procedure PostRotate(const AAngle, AX, AY: Double); overload; procedure PostRotate(const AAngle: Double; const APoint: TBLPointI); overload; procedure PostRotate(const AAngle: Double; const APoint: TBLPoint); overload; procedure PostTransform(const AMatrix: TBLMatrix2D); procedure UserToMeta; procedure GetFillStyle(out ARgba: TBLRgba32); overload; procedure GetFillStyle(out ARgba: TBLRgba64); overload; procedure GetFillStyle(out ARgba: TBLRgba); overload; procedure GetFillStyle(out APattern: IBLPattern); overload; procedure GetFillStyle(out AGradient: IBLGradient); overload; procedure SetFillStyle(const ARgba: TBLRgba32); overload; procedure SetFillStyle(const ARgba: TBLRgba64); overload; procedure SetFillStyle(const ARgba: TBLRgba); overload; procedure SetFillStyle(const APattern: IBLPattern); overload; procedure SetFillStyle(const AGradient: IBLGradient); overload; procedure SetFillStyle(const AImage: IBLImage); overload; procedure GetStrokeStyle(out ARgba: TBLRgba32); overload; procedure GetStrokeStyle(out ARgba: TBLRgba64); overload; procedure GetStrokeStyle(out ARgba: TBLRgba); overload; procedure GetStrokeStyle(out APattern: IBLPattern); overload; procedure GetStrokeStyle(out AGradient: IBLGradient); overload; procedure SetStrokeStyle(const ARgba: TBLRgba32); overload; procedure SetStrokeStyle(const ARgba: TBLRgba64); overload; procedure SetStrokeStyle(const ARgba: TBLRgba); overload; procedure SetStrokeStyle(const APattern: IBLPattern); overload; procedure SetStrokeStyle(const AGradient: IBLGradient); overload; procedure SetStrokeStyle(const AImage: IBLImage); overload; procedure RestoreClipping; procedure ClipToRect(const ARect: TBLRectI); overload; procedure ClipToRect(const ARect: TBLRect); overload; procedure ClipToRect(const AX, AY, AW, AH: Double); overload; procedure ClearAll; procedure ClearRect(const ARect: TBLRectI); overload; procedure ClearRect(const ARect: TBLRect); overload; procedure ClearRect(const AX, AY, AW, AH: Double); overload; procedure FillAll; procedure FillBox(const ABox: TBLBoxI); overload; procedure FillBox(const ABox: TBLBox); overload; procedure FillBox(const AX0, AY0, AX1, AY1: Double); overload; procedure FillRect(const ARect: TBLRectI); overload; procedure FillRect(const ARect: TBLRect); overload; procedure FillRect(const AX, AY, AW, AH: Double); overload; procedure FillCircle(const ACircle: TBLCircle); overload; procedure FillCircle(const ACX, ACY, AR: Double); overload; procedure FillEllipse(const AEllipse: TBLEllipse); overload; procedure FillEllipse(const ACX, ACY, ARX, ARY: Double); overload; procedure FillRoundRect(const ARoundRect: TBLRoundRect); overload; procedure FillRoundRect(const ARect: TBLRect; const AR: Double); overload; procedure FillRoundRect(const ARect: TBLRect; const ARX, ARY: Double); overload; procedure FillRoundRect(const AX, AY, AW, AH, AR: Double); overload; procedure FillRoundRect(const AX, AY, AW, AH, ARX, ARY: Double); overload; procedure FillChord(const AChord: TBLArc); overload; procedure FillChord(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure FillChord(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; procedure FillPie(const APie: TBLArc); overload; procedure FillPie(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure FillPie(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; procedure FillTriangle(const ATriangle: TBLTriangle); overload; procedure FillTriangle(const AX0, AY0, AX1, AY1, AX2, AY2: Double); overload; procedure FillPolygon(const APoly: TArray); overload; procedure FillPolygon(const APoly: TBLArrayView); overload; procedure FillPolygon(const APoly: PBLPoint; const ACount: Integer); overload; procedure FillPolygon(const APoly: TArray); overload; procedure FillPolygon(const APoly: TBLArrayView); overload; procedure FillPolygon(const APoly: PBLPointI; const ACount: Integer); overload; procedure FillBoxArray(const ABoxes: TArray); overload; procedure FillBoxArray(const ABoxes: TBLArrayView); overload; procedure FillBoxArray(const ABoxes: PBLBox; const ACount: Integer); overload; procedure FillBoxArray(const ABoxes: TArray); overload; procedure FillBoxArray(const ABoxes: TBLArrayView); overload; procedure FillBoxArray(const ABoxes: PBLBoxI; const ACount: Integer); overload; procedure FillRectArray(const ARects: TArray); overload; procedure FillRectArray(const ARects: TBLArrayView); overload; procedure FillRectArray(const ARects: PBLRect; const ACount: Integer); overload; procedure FillRectArray(const ARects: TArray); overload; procedure FillRectArray(const ARects: TBLArrayView); overload; procedure FillRectArray(const ARects: PBLRectI; const ACount: Integer); overload; procedure FillRegion(const ARegion: IBLRegion); procedure FillPath(const APath: IBLPath); procedure FillText(const ADst: TBLPointI; const AFont: IBLFont; const AText: String); overload; procedure FillText(const ADst: TBLPoint; const AFont: IBLFont; const AText: String); overload; procedure FillText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UTF8String); overload; procedure FillText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UTF8String); overload; procedure FillText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UCS4String); overload; procedure FillText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UCS4String); overload; procedure FillGlyphRun(const ADst: TBLPointI; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); overload; procedure FillGlyphRun(const ADst: TBLPoint; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); overload; procedure FillGlyphRun(const ADst: TBLPointI; const AFont: IBLFont; const AGlyphRun: PBLGlyphRun); overload; procedure FillGlyphRun(const ADst: TBLPoint; const AFont: IBLFont; const AGlyphRun: PBLGlyphRun); overload; procedure StrokeBox(const ABox: TBLBoxI); overload; procedure StrokeBox(const ABox: TBLBox); overload; procedure StrokeBox(const AX0, AY0, AX1, AY1: Double); overload; procedure StrokeRect(const ARect: TBLRectI); overload; procedure StrokeRect(const ARect: TBLRect); overload; procedure StrokeRect(const AX, AY, AW, AH: Double); overload; procedure StrokeLine(const ALine: TBLLine); overload; procedure StrokeLine(const AP0, AP1: TBLPoint); overload; procedure StrokeLine(const AX0, AY0, AX1, AY1: Double); overload; procedure StrokeCircle(const ACircle: TBLCircle); overload; procedure StrokeCircle(const ACX, ACY, AR: Double); overload; procedure StrokeEllipse(const AEllipse: TBLEllipse); overload; procedure StrokeEllipse(const ACX, ACY, ARX, ARY: Double); overload; procedure StrokeRoundRect(const ARoundRect: TBLRoundRect); overload; procedure StrokeRoundRect(const ARect: TBLRect; const AR: Double); overload; procedure StrokeRoundRect(const ARect: TBLRect; const ARX, ARY: Double); overload; procedure StrokeRoundRect(const AX, AY, AW, AH, AR: Double); overload; procedure StrokeRoundRect(const AX, AY, AW, AH, ARX, ARY: Double); overload; procedure StrokeArc(const AArc: TBLArc); overload; procedure StrokeArc(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure StrokeArc(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; procedure StrokeChord(const AChord: TBLArc); overload; procedure StrokeChord(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure StrokeChord(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; procedure StrokePie(const APie: TBLArc); overload; procedure StrokePie(const ACX, ACY, AR, AStart, ASweep: Double); overload; procedure StrokePie(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); overload; procedure StrokeTriangle(const ATriangle: TBLTriangle); overload; procedure StrokeTriangle(const AX0, AY0, AX1, AY1, AX2, AY2: Double); overload; procedure StrokePolyline(const APoly: TArray); overload; procedure StrokePolyline(const APoly: TBLArrayView); overload; procedure StrokePolyline(const APoly: PBLPoint; const ACount: Integer); overload; procedure StrokePolyline(const APoly: TArray); overload; procedure StrokePolyline(const APoly: TBLArrayView); overload; procedure StrokePolyline(const APoly: PBLPointI; const ACount: Integer); overload; procedure StrokePolygon(const APoly: TArray); overload; procedure StrokePolygon(const APoly: TBLArrayView); overload; procedure StrokePolygon(const APoly: PBLPoint; const ACount: Integer); overload; procedure StrokePolygon(const APoly: TArray); overload; procedure StrokePolygon(const APoly: TBLArrayView); overload; procedure StrokePolygon(const APoly: PBLPointI; const ACount: Integer); overload; procedure StrokeBoxArray(const ABoxes: TArray); overload; procedure StrokeBoxArray(const ABoxes: TBLArrayView); overload; procedure StrokeBoxArray(const ABoxes: PBLBox; const ACount: Integer); overload; procedure StrokeBoxArray(const ABoxes: TArray); overload; procedure StrokeBoxArray(const ABoxes: TBLArrayView); overload; procedure StrokeBoxArray(const ABoxes: PBLBoxI; const ACount: Integer); overload; procedure StrokeRectArray(const ARects: TArray); overload; procedure StrokeRectArray(const ARects: TBLArrayView); overload; procedure StrokeRectArray(const ARects: PBLRect; const ACount: Integer); overload; procedure StrokeRectArray(const ARects: TArray); overload; procedure StrokeRectArray(const ARects: TBLArrayView); overload; procedure StrokeRectArray(const ARects: PBLRectI; const ACount: Integer); overload; procedure StrokePath(const APath: IBLPath); procedure StrokeText(const ADst: TBLPointI; const AFont: IBLFont; const AText: String); overload; procedure StrokeText(const ADst: TBLPoint; const AFont: IBLFont; const AText: String); overload; procedure StrokeText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UTF8String); overload; procedure StrokeText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UTF8String); overload; procedure StrokeText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UCS4String); overload; procedure StrokeText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UCS4String); overload; procedure StrokeGlyphRun(const ADst: TBLPointI; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); overload; procedure StrokeGlyphRun(const ADst: TBLPoint; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); overload; procedure BlitImage(const ADst: TBLPoint; const ASrc: IBLImage); overload; procedure BlitImage(const ADst: TBLPointI; const ASrc: IBLImage); overload; procedure BlitImage(const ADst: TBLPoint; const ASrc: IBLImage; const ASrcArea: TBLRectI); overload; procedure BlitImage(const ADst: TBLPointI; const ASrc: IBLImage; const ASrcArea: TBLRectI); overload; procedure BlitImage(const ADst: TBLRect; const ASrc: IBLImage); overload; procedure BlitImage(const ADst: TBLRectI; const ASrc: IBLImage); overload; procedure BlitImage(const ADst: TBLRect; const ASrc: IBLImage; const ASrcArea: TBLRectI); overload; procedure BlitImage(const ADst: TBLRectI; const ASrc: IBLImage; const ASrcArea: TBLRectI); overload; public procedure AfterConstruction; override; {$ENDREGION 'Internal Declarations'} public { Creates a default constructed rendering context. Default constructed means that the instance is valid, but uninitialized, which means the rendering context does not have attached any target. Any attempt to use uninitialized context results in TBLResultCode.NotInitialized error. } constructor Create; overload; { Creates a new rendering context for rendering to the image ATarget. } constructor Create(const ATarget: IBLImage); overload; { Creates a new rendering context for rendering to the image ATarget. This overload accepts create options that can be used to change the implementation of the rendering context. } constructor Create(const ATarget: IBLImage; const ACreateInfo: TBLContextCreateInfo); overload; destructor Destroy; override; function Equals(Obj: TObject): Boolean; overload; override; end; {$ENDREGION 'Context'} {$REGION 'Runtime'} { ============================================================================ [Constants] ============================================================================ } { Blend2D runtime limits. Note: These constanst are used across Blend2D, but they are not designed to be ABI stable. New versions of Blend2D can increase certain limits without notice. Use runtime to query the limits dynamically, see TBLRuntimeBuildInfo. } const { Maximum width and height of an image. } BL_MAX_IMAGE_SIZE = BL_RUNTIME_MAX_IMAGE_SIZE; { Maximum number of threads for asynchronous operations (including rendering). } BL_MAX_THREAD_COUNT = BL_RUNTIME_MAX_THREAD_COUNT; { ============================================================================ [Enums] ============================================================================ } type { Blend2D runtime build type. } TBLRuntimeBuildType = ( { Describes a Blend2D debug build. } Debug = BL_RUNTIME_BUILD_TYPE_DEBUG, { Describes a Blend2D release build. } Release = BL_RUNTIME_BUILD_TYPE_RELEASE); type { CPU architectures } TBLRuntimeCpuArch = ( { Unknown architecture. } Unknown = BL_RUNTIME_CPU_ARCH_UNKNOWN, { 32-bit or 64-bit X86 architecture. } X86 = BL_RUNTIME_CPU_ARCH_X86, { 32-bit or 64-bit ARM architecture. } ARM = BL_RUNTIME_CPU_ARCH_ARM, { 32-bit or 64-bit MIPS architecture. } MIPS = BL_RUNTIME_CPU_ARCH_MIPS); type {! CPU features Blend2D supports. } TBLRuntimeCpuFeature = ( SSE2 = 0, SSE3 = 1, SSSE3 = 2, SSE4_1 = 3, SSE4_2 = 4, AVX = 5, AVX2 = 6); TBLRuntimeCpuFeatures = set of TBLRuntimeCpuFeature; type { Runtime cleanup flags that can be used through BLRuntime.Cleanup } TBLRuntimeCleanupFlag = ( { Cleanup object memory pool. } ObjectPool = 0, { Cleanup zeroed memory pool. } ZeroedPool = 1, { Cleanup thread pool (would join unused threads). } ThreadPool = 4); TBLRuntimeCleanupFlags = set of TBLRuntimeCleanupFlag; type _TBLRuntimeCleanupFlagsHelper = record helper for TBLRuntimeCleanupFlags public const Everything = [TBLRuntimeCleanupFlag.ObjectPool, TBLRuntimeCleanupFlag.ZeroedPool, TBLRuntimeCleanupFlag.ThreadPool]; end; { ============================================================================ [BLRuntime - BuildInfo] ============================================================================ } type { Blend2D build information. } TBLRuntimeBuildInfo = record {$REGION 'Internal Declarations'} private FHandle: BLRuntimeBuildInfo; function GetBuildType: TBLRuntimeBuildType; inline; function GetBaselineCpuFeatures: TBLRuntimeCpuFeatures; inline; function GetSupportedCpuFeatures: TBLRuntimeCpuFeatures; inline; {$ENDREGION 'Internal Declarations'} public { Blend2D version stored as (Major shl 16) or (Minor shl 8) or Patch } property Version: Cardinal read FHandle.version.version; { Decomposed Blend2D version } property PatchVersion: Byte read FHandle.version.patchVersion; property MinorVersion: Byte read FHandle.version.minorVersion; property MajorVersion: Word read FHandle.version.majorVersion; { Blend2D build type } property BuildType: TBLRuntimeBuildType read GetBuildType; { Baseline CPU features. These features describe CPU features that were detected at compile-time. Baseline features are used to compile all source files so they represent the minimum feature-set the target CPU must support to run Blend2D. Official Blend2D builds set baseline at SSE2 on X86 target and NEON on ARM target. Custom builds can set use different baseline. } property BaselineCpuFeatures: TBLRuntimeCpuFeatures read GetBaselineCpuFeatures; { Supported CPU features. These features do not represent the features that the host CPU must support, instead, they represent all features that Blend2D can take advantage of in C++ code that uses instruction intrinsics. For example if AVX2 is part of SupportedCpuFeatures it means that Blend2D can take advantage of it if there is a separate code-path. } property SupportedCpuFeatures: TBLRuntimeCpuFeatures read GetSupportedCpuFeatures; { Maximum size of an image (both width and height). } property MaxImageSize: Integer read FHandle.maxImageSize; { Maximum number of threads for asynchronous operations, including rendering. } property MaxThreadCount: Integer read FHandle.maxThreadCount; end; PBLRuntimeBuildInfo = ^TBLRuntimeBuildInfo; { ============================================================================ [BLRuntime - SystemInfo] ============================================================================ } type { System information queried by the runtime. } TBLRuntimeSystemInfo = record {$REGION 'Internal Declarations'} private FHandle: BLRuntimeSystemInfo; function GetCpuArch: TBLRuntimeCpuArch; inline; function GetCpuFeatures: TBLRuntimeCpuFeatures; inline; {$ENDREGION 'Internal Declarations'} public { Host CPU architecture } property CpuArch: TBLRuntimeCpuArch read GetCpuArch; { Host CPU features } property CpuFeatures: TBLRuntimeCpuFeatures read GetCpuFeatures; { Number of cores of the host CPU/CPUs. } property CoreCount: Integer read FHandle.coreCount; { Number of threads of the host CPU/CPUs. } property ThreadCount: Integer read FHandle.threadCount; { Minimum stack size of a worker thread used by Blend2D. } property ThreadStackSize: Integer read FHandle.threadStackSize; { Allocation granularity of virtual memory (includes thread's stack). } property AllocationGranularity: Integer read FHandle.allocationGranularity; end; PBLRuntimeSystemInfo = ^TBLRuntimeSystemInfo; { ============================================================================ [BLRuntime - MemoryInfo] ============================================================================ } type { Provides information about resources allocated by Blend2D. } TBLRuntimeResourceInfo = record {$REGION 'Internal Declarations'} private FHandle: BLRuntimeResourceInfo; {$ENDREGION 'Internal Declarations'} public { Virtual memory used at this time. } property VMUsed: NativeInt read FHandle.vmUsed; { Virtual memory reserved (allocated internally). } property VMReserved: NativeInt read FHandle.vmReserved; { Overhead required to manage virtual memory allocations. } property VMOverhead: NativeInt read FHandle.vmOverhead; { Number of blocks of virtual memory allocated. } property VMBlockCount: NativeInt read FHandle.vmBlockCount; { Zeroed memory used at this time. } property ZMUsed: NativeInt read FHandle.zmUsed; { Zeroed memory reserved (allocated internally). } property ZMReserved: NativeInt read FHandle.zmReserved; { Overhead required to manage zeroed memory allocations. } property ZMOverhead: NativeInt read FHandle.zmOverhead; { Number of blocks of zeroed memory allocated. } property ZMBlockCount: NativeInt read FHandle.zmBlockCount; { Count of dynamic pipelines created and cached. } property DynamicPipelineCount: NativeInt read FHandle.dynamicPipelineCount; { Number of active file handles used by Blend2D. Note: File handles are counted by IBLFile - when a file is opened a global counter is incremented and when it's closed it's decremented. This means that this number represents the actual use of IBLFile and doesn't consider the origin of the use (it's either Blend2D or user). } property FileHandleCount: NativeInt read FHandle.fileHandleCount; { Number of active file mappings used by Blend2D. Note: Blend2D maps file content to TBytes container, so this number represents the actual number of TBytes instances that contain a mapped file. } property FileMappingCount: NativeInt read FHandle.fileMappingCount; end; PBLRuntimeMemoryInfo = ^TBLRuntimeResourceInfo; { ============================================================================ [BLRuntime] ============================================================================ } type TBLRuntime = class // static public class procedure Cleanup(const AFlags: TBLRuntimeCleanupFlags); static; class procedure QueryBuildInfo(out AInfo: TBLRuntimeBuildInfo); static; class procedure QuerySystemInfo(out AInfo: TBLRuntimeSystemInfo); static; class procedure QueryResourceInfo(out AInfo: TBLRuntimeResourceInfo); static; class procedure LogMessage(const AMessage: String); overload; static; class procedure LogMessage(const AMessage: String; const AArgs: array of const); overload; static; end; {$ENDREGION 'Runtime'} {$REGION 'Internal'} procedure _BLCheck(const AResult: BLResultCode); {$ENDREGION 'Internal'} implementation uses System.TypInfo; {$POINTERMATH ON} {$REGION 'Utils'} type IBLArray = interface ['{F0CABAA5-F756-483D-95F1-4EBC134793D9}'] function Handle: PBLArrayCore; procedure RevokeOwnership; end; type TBLArray = class(TInterfacedObject, IBLArray) private FHandle: BLArrayCore; FIsReference: Boolean; protected { IBLArray } function Handle: PBLArrayCore; procedure RevokeOwnership; public constructor Create(const AType: BLImplType); destructor Destroy; override; end; type TBLUtils = class // static public class function ArrayElementType: BLImplType; static; class function CreateBLArray: IBLArray; static; class function BLArrayToArray(const AArray: BLArrayCore): TArray; overload; static; class function BLArrayToArray(const AArray: IBLArray): TArray; overload; static; class function ArrayToBLArray(const AArray: TArray): IBLArray; static; end; { TBLArray } constructor TBLArray.Create(const AType: BLImplType); begin inherited Create; blArrayInit(@FHandle, AType); end; destructor TBLArray.Destroy; begin if (not FIsReference) then blArrayDestroy(@FHandle); inherited; end; function TBLArray.Handle: PBLArrayCore; begin Result := @FHandle; end; procedure TBLArray.RevokeOwnership; begin FIsReference := True; end; { TBLUtils } class function TBLUtils.ArrayElementType: BLImplType; var Info: PTypeInfo; Data: PTypeData; begin Info := TypeInfo(T); case GetTypeKind(T) of tkInteger, tkEnumeration: case GetTypeData(Info)^.OrdType of otSByte: Exit(BL_IMPL_TYPE_ARRAY_I8); otUByte: Exit(BL_IMPL_TYPE_ARRAY_U8); otSWord: Exit(BL_IMPL_TYPE_ARRAY_I16); otUWord: Exit(BL_IMPL_TYPE_ARRAY_U16); otSLong: Exit(BL_IMPL_TYPE_ARRAY_I32); otULong: Exit(BL_IMPL_TYPE_ARRAY_U32); end; tkInt64: begin Data := GetTypeData(Info); if (Data^.MaxInt64Value > Data^.MinInt64Value) then Exit(BL_IMPL_TYPE_ARRAY_I64) else Exit(BL_IMPL_TYPE_ARRAY_U64); end; tkFloat: begin Data := GetTypeData(Info); case Data^.FloatType of ftSingle : Exit(BL_IMPL_TYPE_ARRAY_F32); ftDouble : Exit(BL_IMPL_TYPE_ARRAY_F64); end; end; tkRecord: case SizeOf(T) of 1: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_1); 2: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_2); 3: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_3); 4: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_4); 6: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_6); 8: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_8); 10: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_10); 12: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_12); 16: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_16); 20: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_20); 24: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_24); 32: Exit(BL_IMPL_TYPE_ARRAY_STRUCT_32); end; end; Assert(False, 'Unsupported array element type'); Result := BL_IMPL_TYPE_NULL; end; class function TBLUtils.ArrayToBLArray(const AArray: TArray): IBLArray; var A: PBLArrayCore; Count: Integer; begin Result := TBLArray.Create(ArrayElementType); Count := Length(AArray); if (Count <> 0) then begin A := Result.Handle; _BLCheck(blArrayReserve(A, Count)); _BLCheck(blArrayAppendView(A, @AArray[0], Count)); end; end; class function TBLUtils.BLArrayToArray(const AArray: BLArrayCore): TArray; var Impl: PBLArrayImpl; Count: Integer; begin Impl := AArray.impl; Assert(Assigned(Impl) and (Impl.itemSize = SizeOf(T))); Count := Impl.size; if (Count = 0) then Exit(nil); SetLength(Result, Count); Move(Impl.data^, Result[0], Count * SizeOf(T)); end; class function TBLUtils.BLArrayToArray(const AArray: IBLArray): TArray; var Impl: PBLArrayImpl; Count: Integer; begin Impl := AArray.Handle.impl; Assert(Assigned(Impl) and (Impl.itemSize = SizeOf(T))); Count := Impl.size; if (Count = 0) then Exit(nil); SetLength(Result, Count); Move(Impl.data^, Result[0], Count * SizeOf(T)); end; class function TBLUtils.CreateBLArray: IBLArray; begin Result := TBLArray.Create(ArrayElementType); end; {$ENDREGION 'Utils'} {$REGION 'Error Handling'} var GErrorHandler: TBLErrorHandler = nil; GErrorUserData: Pointer = nil; GLastError: TBLResultCode = TBLResultCode.Success; procedure BLSetErrorHandler(const AHandler: TBLErrorHandler; const AUserData: Pointer); begin GErrorHandler := AHandler; GErrorUserData := AUserData; end; procedure ExceptionErrorHandler(const AResultCode: TBLResultCode; const AUserData: Pointer); begin raise EBlend2DError.Create(AResultCode); end; procedure BLSetExceptionErrorHandler; begin GErrorHandler := ExceptionErrorHandler; GErrorUserData := nil; end; procedure GetLastErrorHandler(const AResultCode: TBLResultCode; const AUserData: Pointer); begin GLastError := AResultCode; end; function BLGetLastError: TBLResultCode; begin Result := GLastError; GLastError := TBLResultCode.Success; end; procedure BLSetGetLastErrorHandler; begin GErrorHandler := GetLastErrorHandler; GErrorUserData := nil; end; { _TBLResultCodeHelper } function _TBLResultCodeHelper.ToString: String; const ERROR_STRINGS: array [BL_ERROR_START_INDEX..Ord(High(TBLResultCode))] of String = ( 'Out of memory', 'Invalid value/argument', 'Invalid state', 'Invalid handle or file.', 'Value too large', 'Not initialized (some instance is built-in none when it shouldn''t be).', 'Not implemented', 'Operation not permitted', 'IO error', 'Device or resource busy', 'Operation interrupted', 'Try again', 'Timed out', 'Broken pipe', 'File is not seekable', 'Too many levels of symlinks', 'File is too large', 'File/directory already exists', 'Access denied', 'Media changed', 'The file/FS is read-only', 'Device doesn''t exist', 'Not found, no entry (fs)', 'No media in drive/device', 'No more data / end of file', 'No more files', 'No space left on device', 'Directory is not empty', 'Not a file', 'Not a directory', 'Not same device', 'Not a block device', 'File/path name is invalid', 'File/path name is too long', 'Too many open files', 'Too many open files by OS', 'Too many symbolic links on FS', 'Too many threads', 'Thread pool is exhausted and couldn''t acquire the requested thread count', 'File is empty (not specific to any OS error).', 'File open failed', 'Not a root device/directory', 'Unknown system error that failed to translate to Blend2D result code.', 'Invalid data alignment.', 'Invalid data signature or header.', 'Invalid or corrupted data.', 'Invalid string (invalid data of either UTF8, UTF16, or UTF32).', 'Truncated data (more data required than memory/stream provides).', 'Input data too large to be processed.', 'Decompression failed due to invalid data (RLE, Huffman, etc).', 'Invalid geometry (invalid path data or shape).', 'Returned when there is no matching vertex in path data.', 'No matching cookie (BLContext).', 'No states to restore (BLContext).', 'The size of the image is too large.', 'Image codec for a required format doesn''t exist.', 'Unknown or invalid file format that cannot be read.', 'Image codec doesn''t support reading the file format.', 'Image codec doesn''t support writing the file format.', 'Multiple IHDR chunks are not allowed (PNG).', 'Invalid IDAT chunk (PNG).', 'Invalid IEND chunk (PNG).', 'Invalid PLTE chunk (PNG).', 'Invalid tRNS chunk (PNG).', 'Invalid filter type (PNG).', 'Unsupported feature (JPEG).', 'Invalid SOS marker or header (JPEG).', 'Invalid SOF marker (JPEG).', 'Multiple SOF markers (JPEG).', 'Unsupported SOF marker (JPEG).', 'Font doesn''t have any data as it''s not initialized.', 'Font or font-face was not matched (TBLFontManager).', 'Font has no character to glyph mapping data.', 'Font has missing an important table.', 'Font feature is not available.', 'Font has an invalid CFF data.', 'Font program terminated because the execution reached the limit.', 'Invalid glyph identifier.'); begin if (Self = TBLResultCode.Success) then Result := 'Success' else if (Ord(Self) >= Low(ERROR_STRINGS)) and (Ord(Self) <= High(ERROR_STRINGS)) then Result := ERROR_STRINGS[Ord(Self)] else Result := Format('Unknown error (%d)', [Ord(Self)]); end; { EBlend2DError } constructor EBlend2DError.Create(const AResultCode: TBLResultCode); begin inherited Create(AResultCode.ToString); FResultCode := AResultCode; end; {$ENDREGION 'Error Handling'} {$REGION 'General'} { TBLRange } function BLRange(const AStart, AFinish: Integer): TBLRange; inline; begin Result.Reset(AStart, AFinish); end; class operator TBLRange.Equal(const ALeft, ARight: TBLRange): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLRange.Equals(const AOther: TBLRange): Boolean; begin Result := (FHandle.start = AOther.FHandle.start) and (FHandle.&end = AOther.FHandle.&end); end; function TBLRange.GetFinish: Integer; begin Result := FHandle.&end; end; function TBLRange.GetStart: Integer; begin Result := FHandle.start; end; class operator TBLRange.NotEqual(const ALeft, ARight: TBLRange): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLRange.Reset; begin FHandle.start := 0; FHandle.&end := 0; end; procedure TBLRange.Reset(const AStart, AFinish: Integer); begin FHandle.start := AStart; FHandle.&end := AFinish; end; procedure TBLRange.SetFinish(const AValue: Integer); begin FHandle.&end := AValue; end; procedure TBLRange.SetStart(const AValue: Integer); begin FHandle.start := AValue; end; {$ENDREGION 'General'} {$REGION 'Array'} { TBLArrayView } function TBLArrayView.GetLast: Pointer; begin Result := FHandle.data; Inc(P(Result), FHandle.size); end; function TBLArrayView.GetLength: Integer; begin Result := FHandle.size; end; procedure TBLArrayView.Reset; begin FHandle.data := nil; FHandle.size := 0; end; procedure TBLArrayView.Reset(const AData: Pointer; const ALength: Integer); begin FHandle.data := AData; FHandle.size := ALength; end; {$ENDREGION 'Array'} {$REGION 'Color'} { TBLRgba32 } function BLRgba32: TBLRgba32; overload; inline; begin Result.FHandle.value := 0; end; function BLRgba32(const AValue: Cardinal): TBLRgba32; inline; begin Result.FHandle.value := AValue; end; function BLRgba32(const AR, AG, AB: Byte; const AA: Byte = 255): TBLRgba32; overload; inline; begin Result.Reset(AR, AG, AB, AA); end; function BLRgba32(const AValue: TBLRgba64): TBLRgba32; overload; inline; begin Result.Reset(AValue); end; function BLRgba32(const AValue: TBLRgba): TBLRgba32; overload; inline; begin Result.Reset(AValue); end; class operator TBLRgba32.Implicit(const AValue: Cardinal): TBLRgba32; begin Result.FHandle.value := AValue; end; class operator TBLRgba32.Equal(const ALeft, ARight: TBLRgba32): Boolean; begin Result := (ALeft.FHandle.value = ARight.FHandle.value); end; function TBLRgba32.GetIsOpaque: Boolean; begin Result := (FHandle.value >= $FF000000); end; function TBLRgba32.GetIsTransparent: Boolean; begin Result := (FHandle.value <= $00FFFFFF); end; class operator TBLRgba32.Implicit(const AValue: TBLRgba32): Cardinal; begin Result := AValue.FHandle.value; end; class operator TBLRgba32.NotEqual(const ALeft, ARight: TBLRgba32): Boolean; begin Result := (ALeft.FHandle.value <> ARight.FHandle.value); end; procedure TBLRgba32.Reset; begin FHandle.value := 0; end; procedure TBLRgba32.Reset(const AValue: Cardinal); begin FHandle.value := AValue; end; procedure TBLRgba32.Reset(const AR, AG, AB, AA: Byte); begin FHandle.value := (AA shl 24) or (AR shl 16) or (AG shl 8) or AB; end; { TBLRgba64 } function BLRgba64: TBLRgba64; overload; inline; begin Result.FHandle.value := 0; end; function BLRgba64(const AValue: UInt64): TBLRgba64; overload; inline; begin Result.FHandle.value := AValue; end; function BLRgba64(const AR, AG, AB: Word; const AA: Word = $FFFF): TBLRgba64; overload; inline; begin Result.Reset(AR, AG, AB, AA); end; function BLRgba64(const AValue: TBLRgba32): TBLRgba64; overload; inline; begin Result.Reset(AValue); end; function BLRgba64(const AValue: TBLRgba): TBLRgba32; overload; inline; begin Result.Reset(AValue); end; class operator TBLRgba64.Equal(const ALeft, ARight: TBLRgba64): Boolean; begin Result := (ALeft.FHandle.value = ARight.FHandle.value); end; function TBLRgba64.GetIsOpaque: Boolean; begin Result := (FHandle.value >= $FFFF000000000000); end; function TBLRgba64.GetIsTransparent: Boolean; begin Result := (FHandle.value <= $0000FFFFFFFFFFFF); end; class operator TBLRgba64.Implicit(const AValue: UInt64): TBLRgba64; begin Result.FHandle.value := AValue; end; class operator TBLRgba64.Implicit(const AValue: TBLRgba64): UInt64; begin Result := AValue.FHandle.value; end; class operator TBLRgba64.NotEqual(const ALeft, ARight: TBLRgba64): Boolean; begin Result := (ALeft.FHandle.value <> ARight.FHandle.value); end; procedure TBLRgba64.Reset(const AValue: TBLRgba32); begin FHandle.r := AValue.FHandle.r or (AValue.FHandle.r shl 8); FHandle.g := AValue.FHandle.g or (AValue.FHandle.g shl 8); FHandle.b := AValue.FHandle.b or (AValue.FHandle.b shl 8); FHandle.a := AValue.FHandle.a or (AValue.FHandle.a shl 8); end; procedure TBLRgba64.Reset(const AR, AG, AB, AA: Word); begin FHandle.value := (UInt64(AA) shl 48) or (UInt64(AR) shl 32) or (UInt64(AG) shl 16) or UInt64(AB); end; procedure TBLRgba64.Reset(const AValue: UInt64); begin FHandle.value := AValue; end; procedure TBLRgba64.Reset; begin FHandle.value := 0; end; { TBLRgba } function BLRgba: TBLRgba; overload; inline; begin Result.Reset; end; function BLRgba(const AR, AG, AB: Single; const AA: Single = 1): TBLRgba; overload; inline; begin Result.Reset(AR, AG, AB, AA); end; function BLRgba(const ARgba: TBLRgba32): TBLRgba; overload; inline; begin Result.Reset(ARgba); end; function BLRgba(const ARgba: TBLRgba64): TBLRgba; overload; inline; begin Result.Reset(ARgba); end; class operator TBLRgba.Equal(const ALeft, ARight: TBLRgba): Boolean; begin Result := (ALeft.FHandle.r = ARight.FHandle.r) and (ALeft.FHandle.g = ARight.FHandle.g) and (ALeft.FHandle.b = ARight.FHandle.b) and (ALeft.FHandle.a = ARight.FHandle.a); end; class operator TBLRgba.Equal(const ALeft: TBLRgba; const ARight: TBLRgba32): Boolean; begin Result := (ALeft = BLRgba(ARight)); end; class operator TBLRgba.Equal(const ALeft: TBLRgba; const ARight: TBLRgba64): Boolean; begin Result := (ALeft = BLRgba(ARight)); end; function TBLRgba.GetIsOpaque: Boolean; begin Result := (FHandle.a >= 1); end; function TBLRgba.GetIsTransparent: Boolean; begin Result := (FHandle.a = 0); end; class operator TBLRgba.NotEqual(const ALeft: TBLRgba; const ARight: TBLRgba32): Boolean; begin Result := (ALeft <> BLRgba(ARight)); end; class operator TBLRgba.NotEqual(const ALeft: TBLRgba; const ARight: TBLRgba64): Boolean; begin Result := (ALeft <> BLRgba(ARight)); end; class operator TBLRgba.NotEqual(const ALeft, ARight: TBLRgba): Boolean; begin Result := not (ALeft = ARight); end; procedure TBLRgba.Reset(const ARgba: TBLRgba64); const FACTOR = 1.0 / 65535.0; begin FHandle.r := ARgba.R * FACTOR; FHandle.g := ARgba.G * FACTOR; FHandle.b := ARgba.B * FACTOR; FHandle.a := ARgba.A * FACTOR; end; procedure TBLRgba.Reset(const ARgba: TBLRgba32); const FACTOR = 1.0 / 255.0; begin FHandle.r := ARgba.R * FACTOR; FHandle.g := ARgba.G * FACTOR; FHandle.b := ARgba.B * FACTOR; FHandle.a := ARgba.A * FACTOR; end; procedure TBLRgba.Reset; begin FHandle.r := 0; FHandle.g := 0; FHandle.b := 0; FHandle.a := 0; end; procedure TBLRgba.Reset(const AR, AG, AB, AA: Single); begin FHandle.r := AR; FHandle.g := AG; FHandle.b := AB; FHandle.a := AA; end; { _TBLRgba32Helper } procedure _TBLRgba32Helper.Reset(const AValue: TBLRgba64); var Hi, Lo: UInt32; begin Hi := AValue.FHandle.value shr 32; Lo := AValue.FHandle.value; FHandle.value := (Hi and $FF000000) or ((Lo and $FF000000) shr 16) or ((Hi and $0000FF00) shl 8) or ((Lo and $0000FF00) shr 8); end; procedure _TBLRgba32Helper.Reset(const AValue: TBLRgba); begin FHandle.a := EnsureRange(Trunc(AValue.A * 255.0), 0, 255); FHandle.r := EnsureRange(Trunc(AValue.R * 255.0), 0, 255); FHandle.g := EnsureRange(Trunc(AValue.G * 255.0), 0, 255); FHandle.b := EnsureRange(Trunc(AValue.B * 255.0), 0, 255); end; { _TBLRgba64Helper } procedure _TBLRgba64Helper.Reset(const AValue: TBLRgba); begin FHandle.a := EnsureRange(Trunc(AValue.A * 65535.0), 0, 65535); FHandle.r := EnsureRange(Trunc(AValue.R * 65535.0), 0, 65535); FHandle.g := EnsureRange(Trunc(AValue.G * 65535.0), 0, 65535); FHandle.b := EnsureRange(Trunc(AValue.B * 65535.0), 0, 65535); end; {$ENDREGION 'Color'} {$REGION 'Geometry'} function BLPointI: TBLPointI; overload; inline; begin Result.Reset; end; function BLPointI(const AX, AY: Integer): TBLPointI; overload; inline; begin Result.Reset(AX, AY); end; { TBLPointI } class operator TBLPointI.Add(const ALeft, ARight: TBLPointI): TBLPointI; begin Result.Reset(ALeft.FHandle.x + ARight.FHandle.x, ALeft.FHandle.y + ARight.FHandle.y); end; class operator TBLPointI.Add(const ALeft: Integer; const ARight: TBLPointI): TBLPointI; begin Result.Reset(ALeft + ARight.FHandle.x, ALeft + ARight.FHandle.y); end; class operator TBLPointI.Add(const ALeft: TBLPointI; const ARight: Integer): TBLPointI; begin Result.Reset(ALeft.FHandle.x + ARight, ALeft.FHandle.y + ARight); end; class operator TBLPointI.Equal(const ALeft, ARight: TBLPointI): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLPointI.Equals(const AOther: TBLPointI): Boolean; begin Result := (FHandle.x = AOther.FHandle.x) and (FHandle.y = AOther.FHandle.y); end; class operator TBLPointI.IntDivide(const ALeft: TBLPointI; const ARight: Integer): TBLPointI; begin Result.Reset(ALeft.FHandle.x div ARight, ALeft.FHandle.y div ARight); end; class operator TBLPointI.IntDivide(const ALeft: Integer; const ARight: TBLPointI): TBLPointI; begin Result.Reset(ALeft div ARight.FHandle.x, ALeft div ARight.FHandle.y); end; class operator TBLPointI.IntDivide(const ALeft, ARight: TBLPointI): TBLPointI; begin Result.Reset(ALeft.FHandle.x div ARight.FHandle.x, ALeft.FHandle.y div ARight.FHandle.y); end; class operator TBLPointI.Multiply(const ALeft, ARight: TBLPointI): TBLPointI; begin Result.Reset(ALeft.FHandle.x * ARight.FHandle.x, ALeft.FHandle.y * ARight.FHandle.y); end; class operator TBLPointI.Multiply(const ALeft: Integer; const ARight: TBLPointI): TBLPointI; begin Result.Reset(ALeft * ARight.FHandle.x, ALeft * ARight.FHandle.y); end; class operator TBLPointI.Multiply(const ALeft: TBLPointI; const ARight: Integer): TBLPointI; begin Result.Reset(ALeft.FHandle.x * ARight, ALeft.FHandle.y * ARight); end; class operator TBLPointI.Negative(const AValue: TBLPointI): TBLPointI; begin Result.Reset(-AValue.FHandle.x, -AValue.FHandle.y); end; class operator TBLPointI.NotEqual(const ALeft, ARight: TBLPointI): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLPointI.Reset(const AX, AY: Integer); begin FHandle.x := AX; FHandle.y := AY; end; class operator TBLPointI.Subtract(const ALeft: TBLPointI; const ARight: Integer): TBLPointI; begin Result.Reset(ALeft.FHandle.x - ARight, ALeft.FHandle.y - ARight); end; class operator TBLPointI.Subtract(const ALeft: Integer; const ARight: TBLPointI): TBLPointI; begin Result.Reset(ALeft - ARight.FHandle.x, ALeft - ARight.FHandle.y); end; class operator TBLPointI.Subtract(const ALeft, ARight: TBLPointI): TBLPointI; begin Result.Reset(ALeft.FHandle.x - ARight.FHandle.x, ALeft.FHandle.y - ARight.FHandle.y); end; procedure TBLPointI.Reset; begin FHandle.x := 0; FHandle.y := 0; end; { TBLSizeI } function BLSizeI: TBLSizeI; overload; inline; begin Result.Reset; end; function BLSizeI(const AW, AH: Integer): TBLSizeI; overload; inline; begin Result.Reset(AW, AH); end; class operator TBLSizeI.Equal(const ALeft, ARight: TBLSizeI): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLSizeI.Equals(const AOther: TBLSizeI): Boolean; begin Result := (FHandle.w = AOther.FHandle.w) and (FHandle.h = AOther.FHandle.h); end; class operator TBLSizeI.NotEqual(const ALeft, ARight: TBLSizeI): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLSizeI.Reset(const AW, AH: Integer); begin FHandle.w := AW; FHandle.h := AH; end; procedure TBLSizeI.Reset; begin FHandle.w := 0; FHandle.h := 0; end; { TBLBoxI } function BLBoxI: TBLBoxI; overload; inline; begin Result.Reset; end; function BLBoxI(const AX0, AY0, AX1, AY1: Integer): TBLBoxI; overload; inline; begin Result.Reset(AX0, AY0, AX1, AY1); end; function TBLBoxI.Contains(const AX, AY: Integer): Boolean; begin Result := (AX >= FHandle.x0) and (AY >= FHandle.y0) and (AX < FHandle.x1) and (AY < FHandle.y1); end; function TBLBoxI.Contains(const AP: TBLPointI): Boolean; begin Result := (AP.FHandle.x >= FHandle.x0) and (AP.FHandle.y >= FHandle.y0) and (AP.FHandle.x < FHandle.x1) and (AP.FHandle.y < FHandle.y1); end; class operator TBLBoxI.Equal(const ALeft, ARight: TBLBoxI): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLBoxI.Equals(const AOther: TBLBoxI): Boolean; begin Result := (FHandle.x0 = AOther.FHandle.x0) and (FHandle.y0 = AOther.FHandle.y0) and (FHandle.x1 = AOther.FHandle.x1) and (FHandle.y1 = AOther.FHandle.y0); end; function TBLBoxI.GetHeight: Integer; begin Result := FHandle.y1 - FHandle.y0; end; function TBLBoxI.GetWidth: Integer; begin Result := FHandle.x1 - FHandle.y0; end; class operator TBLBoxI.NotEqual(const ALeft, ARight: TBLBoxI): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLBoxI.Reset(const AX0, AY0, AX1, AY1: Integer); begin FHandle.x0 := AX0; FHandle.y0 := AY0; FHandle.x1 := AX1; FHandle.y1 := AY1; end; procedure TBLBoxI.Reset; begin FHandle.x0 := 0; FHandle.y0 := 0; FHandle.x1 := 0; FHandle.y1 := 0; end; procedure TBLBoxI.SetHeight(const AValue: Integer); begin FHandle.y1 := FHandle.y0 + AValue; end; procedure TBLBoxI.SetWidth(const AValue: Integer); begin FHandle.x1 := FHandle.x0 + AValue; end; { TBLRectI } function BLRectI: TBLRectI; inline; begin Result.Reset; end; function BLRectI(const AX, AY, AW, AH: Integer): TBLRectI; inline; begin Result.Reset(AX, AY, AW, AH); end; class operator TBLRectI.Equal(const ALeft, ARight: TBLRectI): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLRectI.Equals(const AOther: TBLRectI): Boolean; begin Result := (FHandle.x = AOther.FHandle.x) and (FHandle.y = AOther.FHandle.y) and (FHandle.w = AOther.FHandle.w) and (FHandle.h = AOther.FHandle.h); end; class operator TBLRectI.NotEqual(const ALeft, ARight: TBLRectI): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLRectI.Reset(const AX, AY, AW, AH: Integer); begin FHandle.x := AX; FHandle.y := AY; FHandle.w := AW; FHandle.h := AH; end; procedure TBLRectI.Reset; begin FHandle.x := 0; FHandle.y := 0; FHandle.w := 0; FHandle.h := 0; end; { TBLPoint } function BLPoint: TBLPoint; overload; inline; begin Result.Reset; end; function BLPoint(const AX, AY: Double): TBLPoint; inline; begin Result.Reset(AX, AY); end; class operator TBLPoint.Add(const ALeft, ARight: TBLPoint): TBLPoint; begin Result.Reset(ALeft.FHandle.x + ARight.FHandle.x, ALeft.FHandle.y + ARight.FHandle.y); end; class operator TBLPoint.Divide(const ALeft: TBLPoint; const ARight: Double): TBLPoint; begin Result.Reset(ALeft.FHandle.x / ARight, ALeft.FHandle.y / ARight); end; class operator TBLPoint.Divide(const ALeft: Double; const ARight: TBLPoint): TBLPoint; begin Result.Reset(ALeft / ARight.FHandle.x, ALeft / ARight.FHandle.y); end; class operator TBLPoint.Divide(const ALeft, ARight: TBLPoint): TBLPoint; begin Result.Reset(ALeft.FHandle.x / ARight.FHandle.x, ALeft.FHandle.y / ARight.FHandle.y); end; class operator TBLPoint.Add(const ALeft: Double; const ARight: TBLPoint): TBLPoint; begin Result.Reset(ALeft + ARight.FHandle.x, ALeft + ARight.FHandle.y); end; class operator TBLPoint.Add(const ALeft: TBLPoint; const ARight: Double): TBLPoint; begin Result.Reset(ALeft.FHandle.x + ARight, ALeft.FHandle.y + ARight); end; class operator TBLPoint.Equal(const ALeft, ARight: TBLPoint): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLPoint.Equals(const AOther: TBLPoint): Boolean; begin Result := (FHandle.x = AOther.FHandle.x) and (FHandle.y = AOther.FHandle.y); end; class operator TBLPoint.Multiply(const ALeft, ARight: TBLPoint): TBLPoint; begin Result.Reset(ALeft.FHandle.x * ARight.FHandle.x, ALeft.FHandle.y * ARight.FHandle.y); end; class operator TBLPoint.Multiply(const ALeft: Double; const ARight: TBLPoint): TBLPoint; begin Result.Reset(ALeft * ARight.FHandle.x, ALeft * ARight.FHandle.y); end; class operator TBLPoint.Multiply(const ALeft: TBLPoint; const ARight: Double): TBLPoint; begin Result.Reset(ALeft.FHandle.x * ARight, ALeft.FHandle.y * ARight); end; class operator TBLPoint.Negative(const AValue: TBLPoint): TBLPoint; begin Result.Reset(-AValue.FHandle.x, -AValue.FHandle.y); end; class operator TBLPoint.NotEqual(const ALeft, ARight: TBLPoint): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLPoint.Reset(const AX, AY: Double); begin FHandle.x := AX; FHandle.y := AY; end; class operator TBLPoint.Subtract(const ALeft: TBLPoint; const ARight: Double): TBLPoint; begin Result.Reset(ALeft.FHandle.x - ARight, ALeft.FHandle.y - ARight); end; class operator TBLPoint.Subtract(const ALeft: Double; const ARight: TBLPoint): TBLPoint; begin Result.Reset(ALeft - ARight.FHandle.x, ALeft - ARight.FHandle.y); end; class operator TBLPoint.Subtract(const ALeft, ARight: TBLPoint): TBLPoint; begin Result.Reset(ALeft.FHandle.x - ARight.FHandle.x, ALeft.FHandle.y - ARight.FHandle.y); end; procedure TBLPoint.Reset; begin FHandle.x := 0; FHandle.y := 0; end; { TBLSize } function BLSize: TBLSize; overload; inline; begin Result.Reset; end; function BLSize(const AW, AH: Double): TBLSize; overload; inline; begin Result.Reset(AW, AH); end; class operator TBLSize.Equal(const ALeft, ARight: TBLSize): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLSize.Equals(const AOther: TBLSize): Boolean; begin Result := (FHandle.w = AOther.FHandle.w) and (FHandle.h = AOther.FHandle.h); end; class operator TBLSize.NotEqual(const ALeft, ARight: TBLSize): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLSize.Reset(const AW, AH: Double); begin FHandle.w := AW; FHandle.h := AH; end; procedure TBLSize.Reset; begin FHandle.w := 0; FHandle.h := 0; end; { TBLBox } function BLBox: TBLBox; overload; inline; begin Result.Reset; end; function BLBox(const AX0, AY0, AX1, AY1: Double): TBLBox; inline; begin Result.Reset(AX0, AY0, AX1, AY1); end; function TBLBox.Contains(const AX, AY: Double): Boolean; begin Result := (AX >= FHandle.x0) and (AY >= FHandle.y0) and (AX < FHandle.x1) and (AY < FHandle.y1); end; class operator TBLBox.Add(const ALeft: TBLPoint; const ARight: TBLBox): TBLBox; begin Result.Reset(ALeft.FHandle.x + ARight.FHandle.x0, ALeft.FHandle.y + ARight.FHandle.y0, ALeft.FHandle.x + ARight.FHandle.x1, ALeft.FHandle.y + ARight.FHandle.y1); end; class operator TBLBox.Add(const ALeft: TBLBox; const ARight: TBLPoint): TBLBox; begin Result.Reset(ALeft.FHandle.x0 + ARight.FHandle.x, ALeft.FHandle.y0 + ARight.FHandle.y, ALeft.FHandle.x1 + ARight.FHandle.x, ALeft.FHandle.y1 + ARight.FHandle.y); end; class operator TBLBox.Add(const ALeft: Double; const ARight: TBLBox): TBLBox; begin Result.Reset(ALeft + ARight.FHandle.x0, ALeft + ARight.FHandle.y0, ALeft + ARight.FHandle.x1, ALeft + ARight.FHandle.y1); end; class operator TBLBox.Add(const ALeft: TBLBox; const ARight: Double): TBLBox; begin Result.Reset(ALeft.FHandle.x0 + ARight, ALeft.FHandle.y0 + ARight, ALeft.FHandle.x1 + ARight, ALeft.FHandle.y1 + ARight); end; function TBLBox.Contains(const AP: TBLPoint): Boolean; begin Result := (AP.FHandle.x >= FHandle.x0) and (AP.FHandle.y >= FHandle.y0) and (AP.FHandle.x < FHandle.x1) and (AP.FHandle.y < FHandle.y1); end; class operator TBLBox.Divide(const ALeft: TBLPoint; const ARight: TBLBox): TBLBox; begin Result.Reset(ALeft.FHandle.x / ARight.FHandle.x0, ALeft.FHandle.y / ARight.FHandle.y0, ALeft.FHandle.x / ARight.FHandle.x1, ALeft.FHandle.y / ARight.FHandle.y1); end; class operator TBLBox.Divide(const ALeft: TBLBox; const ARight: TBLPoint): TBLBox; begin Result.Reset(ALeft.FHandle.x0 / ARight.FHandle.x, ALeft.FHandle.y0 / ARight.FHandle.y, ALeft.FHandle.x1 / ARight.FHandle.x, ALeft.FHandle.y1 / ARight.FHandle.y); end; class operator TBLBox.Divide(const ALeft: Double; const ARight: TBLBox): TBLBox; begin Result.Reset(ALeft / ARight.FHandle.x0, ALeft / ARight.FHandle.y0, ALeft / ARight.FHandle.x1, ALeft / ARight.FHandle.y1); end; class operator TBLBox.Divide(const ALeft: TBLBox; const ARight: Double): TBLBox; begin Result.Reset(ALeft.FHandle.x0 / ARight, ALeft.FHandle.y0 / ARight, ALeft.FHandle.x1 / ARight, ALeft.FHandle.y1 / ARight); end; class operator TBLBox.Equal(const ALeft, ARight: TBLBox): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLBox.Equals(const AOther: TBLBox): Boolean; begin Result := (FHandle.x0 = AOther.FHandle.x0) and (FHandle.y0 = AOther.FHandle.y0) and (FHandle.x1 = AOther.FHandle.x1) and (FHandle.y1 = AOther.FHandle.y0); end; function TBLBox.GetHeight: Double; begin Result := FHandle.y1 - FHandle.y0; end; function TBLBox.GetWidth: Double; begin Result := FHandle.x1 - FHandle.x0; end; class operator TBLBox.Multiply(const ALeft: TBLPoint; const ARight: TBLBox): TBLBox; begin Result.Reset(ALeft.FHandle.x * ARight.FHandle.x0, ALeft.FHandle.y * ARight.FHandle.y0, ALeft.FHandle.x * ARight.FHandle.x1, ALeft.FHandle.y * ARight.FHandle.y1); end; class operator TBLBox.Multiply(const ALeft: TBLBox; const ARight: TBLPoint): TBLBox; begin Result.Reset(ALeft.FHandle.x0 * ARight.FHandle.x, ALeft.FHandle.y0 * ARight.FHandle.y, ALeft.FHandle.x1 * ARight.FHandle.x, ALeft.FHandle.y1 * ARight.FHandle.y); end; class operator TBLBox.Multiply(const ALeft: Double; const ARight: TBLBox): TBLBox; begin Result.Reset(ALeft * ARight.FHandle.x0, ALeft * ARight.FHandle.y0, ALeft * ARight.FHandle.x1, ALeft * ARight.FHandle.y1); end; class operator TBLBox.Multiply(const ALeft: TBLBox; const ARight: Double): TBLBox; begin Result.Reset(ALeft.FHandle.x0 * ARight, ALeft.FHandle.y0 * ARight, ALeft.FHandle.x1 * ARight, ALeft.FHandle.y1 * ARight); end; class operator TBLBox.NotEqual(const ALeft, ARight: TBLBox): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLBox.Reset; begin FHandle.x0 := 0; FHandle.y0 := 0; FHandle.x1 := 0; FHandle.y1 := 0; end; procedure TBLBox.Reset(const AX0, AY0, AX1, AY1: Double); begin FHandle.x0 := AX0; FHandle.y0 := AY0; FHandle.x1 := AX1; FHandle.y1 := AY1; end; procedure TBLBox.SetHeight(const AValue: Double); begin FHandle.y1 := FHandle.y0 + AValue; end; procedure TBLBox.SetWidth(const AValue: Double); begin FHandle.x1 := FHandle.x0 + AValue; end; class operator TBLBox.Subtract(const ALeft: TBLPoint; const ARight: TBLBox): TBLBox; begin Result.Reset(ALeft.FHandle.x - ARight.FHandle.x0, ALeft.FHandle.y - ARight.FHandle.y0, ALeft.FHandle.x - ARight.FHandle.x1, ALeft.FHandle.y - ARight.FHandle.y1); end; class operator TBLBox.Subtract(const ALeft: TBLBox; const ARight: TBLPoint): TBLBox; begin Result.Reset(ALeft.FHandle.x0 - ARight.FHandle.x, ALeft.FHandle.y0 - ARight.FHandle.y, ALeft.FHandle.x1 - ARight.FHandle.x, ALeft.FHandle.y1 - ARight.FHandle.y); end; class operator TBLBox.Subtract(const ALeft: Double; const ARight: TBLBox): TBLBox; begin Result.Reset(ALeft - ARight.FHandle.x0, ALeft - ARight.FHandle.y0, ALeft - ARight.FHandle.x1, ALeft - ARight.FHandle.y1); end; class operator TBLBox.Subtract(const ALeft: TBLBox; const ARight: Double): TBLBox; begin Result.Reset(ALeft.FHandle.x0 - ARight, ALeft.FHandle.y0 - ARight, ALeft.FHandle.x1 - ARight, ALeft.FHandle.y1 - ARight); end; { TBLRect } function BLRect: TBLRect; overload; inline; begin Result.Reset; end; function BLRect(const AX, AY, AW, AH: Double): TBLRect; inline; begin Result.Reset(AX, AY, AW, AH); end; class operator TBLRect.Equal(const ALeft, ARight: TBLRect): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLRect.Equals(const AOther: TBLRect): Boolean; begin Result := (FHandle.x = AOther.FHandle.x) and (FHandle.y = AOther.FHandle.y) and (FHandle.w = AOther.FHandle.w) and (FHandle.h = AOther.FHandle.h); end; class operator TBLRect.NotEqual(const ALeft, ARight: TBLRect): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLRect.Reset(const AX, AY, AW, AH: Double); begin FHandle.x := AX; FHandle.y := AY; FHandle.w := AW; FHandle.h := AH; end; procedure TBLRect.Reset; begin FHandle.x := 0; FHandle.y := 0; FHandle.w := 0; FHandle.h := 0; end; { TBLLine } function BLLine: TBLLine; overload; inline; begin Result.Reset; end; function BLLine(const AX0, AY0, AX1, AY1: Double): TBLLine; overload; inline; begin Result.Reset(AX0, AY0, AX1, AY1); end; function BLLine(const AP0, AP1: TBLPoint): TBLLine; overload; inline; begin Result.Reset(AP0, AP1); end; class operator TBLLine.Equal(const ALeft, ARight: TBLLine): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLLine.Equals(const AOther: TBLLine): Boolean; begin Result := (FHandle.x0 = AOther.FHandle.x0) and (FHandle.y0 = AOther.FHandle.y0) and (FHandle.x1 = AOther.FHandle.x1) and (FHandle.y1 = AOther.FHandle.y1); end; class operator TBLLine.NotEqual(const ALeft, ARight: TBLLine): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLLine.Reset(const AX0, AY0, AX1, AY1: Double); begin FHandle.x0 := AX0; FHandle.y0 := AY0; FHandle.x1 := AX1; FHandle.y1 := AY1; end; procedure TBLLine.Reset(const AP0, AP1: TBLPoint); begin FHandle.x0 := AP0.FHandle.x; FHandle.y0 := AP0.FHandle.y; FHandle.x1 := AP1.FHandle.x; FHandle.y1 := AP1.FHandle.y; end; procedure TBLLine.Reset; begin FHandle.x0 := 0; FHandle.y0 := 0; FHandle.x1 := 0; FHandle.y1 := 0; end; { TBLTriangle } function BLTriangle: TBLTriangle; overload; inline; begin Result.Reset; end; function BLTriangle(const AX0, AY0, AX1, AY1, AX2, AY2: Double): TBLTriangle; inline; begin Result.Reset(AX0, AY0, AX1, AY1, AX2, AY2); end; class operator TBLTriangle.Equal(const ALeft, ARight: TBLTriangle): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLTriangle.Equals(const AOther: TBLTriangle): Boolean; begin Result := (FHandle.x0 = AOther.FHandle.x0) and (FHandle.y0 = AOther.FHandle.y0) and (FHandle.x1 = AOther.FHandle.x1) and (FHandle.y1 = AOther.FHandle.y1) and (FHandle.x2 = AOther.FHandle.x2) and (FHandle.y2 = AOther.FHandle.y2); end; class operator TBLTriangle.NotEqual(const ALeft, ARight: TBLTriangle): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLTriangle.Reset(const AX0, AY0, AX1, AY1, AX2, AY2: Double); begin FHandle.x0 := AX0; FHandle.y0 := AY0; FHandle.x1 := AX1; FHandle.y1 := AY1; FHandle.x2 := AX2; FHandle.y2 := AY2; end; procedure TBLTriangle.Reset; begin FHandle.x0 := 0; FHandle.y0 := 0; FHandle.x1 := 0; FHandle.y1 := 0; FHandle.x2 := 0; FHandle.y2 := 0; end; { TBLRoundRect } function BLRoundRect: TBLRoundRect; overload; inline; begin Result.Reset; end; function BLRoundRect(const ARect: TBLRect; const AR: Double): TBLRoundRect; overload; inline; begin Result.Reset(ARect, AR); end; function BLRoundRect(const ARect: TBLRect; const ARX, ARY: Double): TBLRoundRect; overload; inline; begin Result.Reset(ARect, ARX, ARY); end; function BLRoundRect(const AX, AY, AW, AH, AR: Double): TBLRoundRect; overload; inline; begin Result.Reset(AX, AY, AW, AH, AR); end; function BLRoundRect(const AX, AY, AW, AH, ARX, ARY: Double): TBLRoundRect; overload; inline; begin Result.Reset(AX, AY, AW, AH, ARX, ARY); end; class operator TBLRoundRect.Equal(const ALeft, ARight: TBLRoundRect): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLRoundRect.Equals(const AOther: TBLRoundRect): Boolean; begin Result := (FHandle.x = AOther.FHandle.x) and (FHandle.y = AOther.FHandle.y) and (FHandle.w = AOther.FHandle.w) and (FHandle.h = AOther.FHandle.h) and (FHandle.rx = AOther.FHandle.rx) and (FHandle.ry = AOther.FHandle.ry); end; class operator TBLRoundRect.NotEqual(const ALeft, ARight: TBLRoundRect): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLRoundRect.Reset(const ARect: TBLRect; const AR: Double); begin FHandle.x := ARect.FHandle.x; FHandle.y := ARect.FHandle.y; FHandle.w := ARect.FHandle.w; FHandle.h := ARect.FHandle.h; FHandle.rx := AR; FHandle.ry := AR; end; procedure TBLRoundRect.Reset(const AX, AY, AW, AH, AR: Double); begin FHandle.x := AX; FHandle.y := AY; FHandle.w := AW; FHandle.h := AH; FHandle.rx := AR; FHandle.ry := AR; end; procedure TBLRoundRect.Reset(const AX, AY, AW, AH, ARX, ARY: Double); begin FHandle.x := AX; FHandle.y := AY; FHandle.w := AW; FHandle.h := AH; FHandle.rx := ARX; FHandle.ry := ARY; end; procedure TBLRoundRect.Reset(const ARect: TBLRect; const ARX, ARY: Double); begin FHandle.x := ARect.FHandle.x; FHandle.y := ARect.FHandle.y; FHandle.w := ARect.FHandle.w; FHandle.h := ARect.FHandle.h; FHandle.rx := ARX; FHandle.ry := ARY; end; procedure TBLRoundRect.Reset; begin FHandle.x := 0; FHandle.y := 0; FHandle.w := 0; FHandle.h := 0; FHandle.rx := 0; FHandle.ry := 0; end; { TBLCircle } function BLCircle: TBLCircle; overload; inline; begin Result.Reset; end; function BLCircle(const ACX, ACY, AR: Double): TBLCircle; inline; begin Result.Reset(ACX, ACY, AR); end; class operator TBLCircle.Equal(const ALeft, ARight: TBLCircle): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLCircle.Equals(const AOther: TBLCircle): Boolean; begin Result := (FHandle.cx = AOther.FHandle.cx) and (FHandle.cy = AOther.FHandle.cy) and (FHandle.r = AOther.FHandle.r); end; class operator TBLCircle.NotEqual(const ALeft, ARight: TBLCircle): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLCircle.Reset(const ACX, ACY, AR: Double); begin FHandle.cx := ACX; FHandle.cy := ACY; FHandle.r := AR; end; procedure TBLCircle.Reset; begin FHandle.cx := 0; FHandle.cy := 0; FHandle.r := 0; end; { TBLEllipse } function BLEllipse: TBLEllipse; overload; inline; begin Result.Reset; end; function BLEllipse(const ACX, ACY, ARX, ARY: Double): TBLEllipse; inline; begin Result.Reset(ACX, ACY, ARX, ARY); end; class operator TBLEllipse.Equal(const ALeft, ARight: TBLEllipse): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLEllipse.Equals(const AOther: TBLEllipse): Boolean; begin Result := (FHandle.cx = AOther.FHandle.cx) and (FHandle.cy = AOther.FHandle.cy) and (FHandle.rx = AOther.FHandle.rx) and (FHandle.ry = AOther.FHandle.ry); end; class operator TBLEllipse.NotEqual(const ALeft, ARight: TBLEllipse): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLEllipse.Reset(const ACX, ACY, ARX, ARY: Double); begin FHandle.cx := ACX; FHandle.cy := ACY; FHandle.rx := ARX; FHandle.ry := ARY; end; procedure TBLEllipse.Reset; begin FHandle.cx := 0; FHandle.cy := 0; FHandle.rx := 0; FHandle.ry := 0; end; { TBLArc } function BLArc: TBLArc; overload; inline; begin Result.Reset; end; function BLArc(const ACX, ACY, AR, AStart, ASweep: Double): TBLArc; overload; inline; begin Result.Reset(ACX, ACY, AR, AStart, ASweep); end; function BLArc(const ACX, ACY, ARX, ARY, AStart, ASweep: Double): TBLArc; overload; inline; begin Result.Reset(ACX, ACY, ARX, ARY, AStart, ASweep); end; class operator TBLArc.Equal(const ALeft, ARight: TBLArc): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLArc.Equals(const AOther: TBLArc): Boolean; begin Result := (FHandle.cx = AOther.FHandle.cx) and (FHandle.cy = AOther.FHandle.cy) and (FHandle.rx = AOther.FHandle.rx) and (FHandle.ry = AOther.FHandle.ry) and (FHandle.start = AOther.FHandle.start) and (FHandle.sweep = AOther.FHandle.sweep); end; class operator TBLArc.NotEqual(const ALeft, ARight: TBLArc): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLArc.Reset(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); begin FHandle.cx := ACX; FHandle.cy := ACY; FHandle.rx := ARX; FHandle.ry := ARY; FHandle.start := AStart; FHandle.sweep := ASweep; end; procedure TBLArc.Reset(const ACX, ACY, AR, AStart, ASweep: Double); begin FHandle.cx := ACX; FHandle.cy := ACY; FHandle.rx := AR; FHandle.ry := AR; FHandle.start := AStart; FHandle.sweep := ASweep; end; procedure TBLArc.Reset; begin FHandle.cx := 0; FHandle.cy := 0; FHandle.rx := 0; FHandle.ry := 0; FHandle.start := 0; FHandle.sweep := 0; end; { Globals } function BLAbs(const AA: TBLPoint): TBLPoint; overload; inline; begin Result.Reset(Abs(AA.FHandle.x), Abs(AA.FHandle.y)); end; function BLAbs(const AA: TBLSize): TBLSize; overload; inline; begin Result.Reset(Abs(AA.FHandle.w), Abs(AA.FHandle.h)); end; function BLMin(const AA, AB: TBLPoint): TBLPoint; overload; inline; begin Result.Reset(Min(AA.FHandle.x, AB.FHandle.x), Min(AA.FHandle.y, AB.FHandle.y)); end; function BLMin(const AA: TBLPoint; const AB: Double): TBLPoint; overload; inline; begin Result.Reset(Min(AA.FHandle.x, AB), Min(AA.FHandle.y, AB)); end; function BLMin(const AA: Double; const AB: TBLPoint): TBLPoint; overload; inline; begin Result.Reset(Min(AA, AB.FHandle.x), Min(AA, AB.FHandle.y)); end; function BLMin(const AA, AB: TBLSize): TBLSize; overload; inline; begin Result.Reset(Min(AA.FHandle.w, AB.FHandle.w), Min(AA.FHandle.h, AB.FHandle.h)); end; function BLMax(const AA, AB: TBLPoint): TBLPoint; overload; inline; begin Result.Reset(Max(AA.FHandle.x, AB.FHandle.x), Max(AA.FHandle.y, AB.FHandle.y)); end; function BLMax(const AA: TBLPoint; const AB: Double): TBLPoint; overload; inline; begin Result.Reset(Max(AA.FHandle.x, AB), Max(AA.FHandle.y, AB)); end; function BLMax(const AA: Double; const AB: TBLPoint): TBLPoint; overload; inline; begin Result.Reset(Max(AA, AB.FHandle.x), Max(AA, AB.FHandle.y)); end; function BLMax(const AA, AB: TBLSize): TBLSize; overload; inline; begin Result.Reset(Max(AA.FHandle.w, AB.FHandle.w), Max(AA.FHandle.h, AB.FHandle.h)); end; function BLClamp(const AA: TBLPoint; const AB, AC: Double): TBLPoint; inline; begin Result := BLMin(AC, BLMax(AA, AB)); end; {$ENDREGION 'Geometry'} {$REGION 'Matrix'} { TBLMatrix2D } function BLMatrix2D: TBLMatrix2D; overload; inline; begin Result.Reset; end; function BLMatrix2D(const AM00, AM01, AM10, AM11, AM20, AM21: Double): TBLMatrix2D; overload; inline; begin Result.Reset(AM00, AM01, AM10, AM11, AM20, AM21); end; class operator TBLMatrix2D.Equal(const ALeft, ARight: TBLMatrix2D): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLMatrix2D.Equals(const AOther: TBLMatrix2D): Boolean; begin Result := (FHandle.m00 = AOther.FHandle.m00) and (FHandle.m01 = AOther.FHandle.m01) and (FHandle.m10 = AOther.FHandle.m10) and (FHandle.m11 = AOther.FHandle.m11) and (FHandle.m20 = AOther.FHandle.m20) and (FHandle.m21 = AOther.FHandle.m21); end; function TBLMatrix2D.GetDeterminant: Double; begin Result := (FHandle.m00 * FHandle.m11) - (FHandle.m01 * FHandle.m10); end; function TBLMatrix2D.GetElement(const AIndex: TBLMatrix2DValue): Double; begin Result := FHandle.m[Ord(AIndex)]; end; function TBLMatrix2D.GetMatrixType: TBLMatrix2DType; begin Result := TBLMatrix2DType(blMatrix2DGetType(@FHandle)); end; class function TBLMatrix2D.Invert(const ASrc: TBLMatrix2D; out ADst: TBLMatrix2D): Boolean; begin Result := (blMatrix2DInvert(@ADst.FHandle, @ASrc.FHandle) = BL_SUCCESS); end; function TBLMatrix2D.Invert: Boolean; begin Result := (blMatrix2DInvert(@FHandle, @FHandle) = BL_SUCCESS); end; class function TBLMatrix2D.MakeIdentity: TBLMatrix2D; begin Result.Reset(1, 0, 0, 1, 0, 0); end; class function TBLMatrix2D.MakeRotation(const AAngle, AX, AY: Double): TBLMatrix2D; begin Result.ResetToRotation(AAngle, AX, AY); end; class function TBLMatrix2D.MakeRotation(const AAngle: Double): TBLMatrix2D; begin Result.ResetToRotation(AAngle, 0, 0); end; class function TBLMatrix2D.MakeRotation(const AAngle: Double; const AP: TBLPoint): TBLMatrix2D; begin Result.ResetToRotation(AAngle, AP.FHandle.x, AP.FHandle.y); end; class function TBLMatrix2D.MakeScaling(const AX, AY: Double): TBLMatrix2D; begin Result.Reset(AX, 0, 0, AY, 0, 0); end; class function TBLMatrix2D.MakeScaling(const AP: TBLPoint): TBLMatrix2D; begin Result.Reset(AP.FHandle.x, 0, 0, AP.FHandle.y, 0, 0); end; class function TBLMatrix2D.MakeScaling(const AP: TBLPointI): TBLMatrix2D; begin Result.Reset(AP.FHandle.x, 0, 0, AP.FHandle.y, 0, 0); end; class function TBLMatrix2D.MakeScaling(const AXY: Double): TBLMatrix2D; begin Result.Reset(AXY, 0, 0, AXY, 0, 0); end; class function TBLMatrix2D.MakeSinCos(const ASin, ACos: Double; const ATranslate: TBLPoint): TBLMatrix2D; begin Result.Reset(ACos, ASin, -ASin, ACos, ATranslate.FHandle.x, ATranslate.FHandle.y); end; class function TBLMatrix2D.MakeSinCos(const ASin, ACos, ATranslateX, ATranslateY: Double): TBLMatrix2D; begin Result.Reset(ACos, ASin, -ASin, ACos, ATranslateX, ATranslateY); end; class function TBLMatrix2D.MakeSkewing(const AX, AY: Double): TBLMatrix2D; begin Result.ResetToSkewing(AX, AY); end; class function TBLMatrix2D.MakeSkewing(const AP: TBLPoint): TBLMatrix2D; begin Result.ResetToSkewing(AP.FHandle.x, AP.FHandle.y); end; class function TBLMatrix2D.MakeTranslation(const AP: TBLPointI): TBLMatrix2D; begin Result.Reset(1, 0, 0, 1, AP.FHandle.x, AP.FHandle.y); end; class function TBLMatrix2D.MakeTranslation(const AP: TBLPoint): TBLMatrix2D; begin Result.Reset(1, 0, 0, 1, AP.FHandle.x, AP.FHandle.y); end; class function TBLMatrix2D.MakeTranslation(const AX, AY: Double): TBLMatrix2D; begin Result.Reset(1, 0, 0, 1, AX, AY); end; function TBLMatrix2D.MapPoint(const AP: TBLPoint): TBLPoint; begin Result.Reset( (AP.FHandle.x * FHandle.m00) + (AP.FHandle.y * FHandle.m10) + FHandle.m20, (AP.FHandle.x * FHandle.m01) + (AP.FHandle.y * FHandle.m11) + FHandle.m21); end; function TBLMatrix2D.MapPoint(const AX, AY: Double): TBLPoint; begin Result.Reset( (AX * FHandle.m00) + (AY * FHandle.m10) + FHandle.m20, (AX * FHandle.m01) + (AY * FHandle.m11) + FHandle.m21); end; function TBLMatrix2D.MapVector(const AX, AY: Double): TBLPoint; begin Result.Reset( (AX * FHandle.m00) + (AY * FHandle.m10), (AX * FHandle.m01) + (AY * FHandle.m11)); end; function TBLMatrix2D.MapVector(const AV: TBLPoint): TBLPoint; begin Result.Reset( (AV.FHandle.x * FHandle.m00) + (AV.FHandle.y * FHandle.m10), (AV.FHandle.x * FHandle.m01) + (AV.FHandle.y * FHandle.m11)); end; class operator TBLMatrix2D.NotEqual(const ALeft, ARight: TBLMatrix2D): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLMatrix2D.PostRotate(const AAngle, AX, AY: Double); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AX; Data[2] := AY; _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLMatrix2D.PostRotate(const AAngle: Double; const AP: TBLPoint); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLMatrix2D.PostRotate(const AAngle: Double); begin _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE, @AAngle)); end; procedure TBLMatrix2D.PostScale(const AP: TBLPoint); begin PostScale(AP.FHandle.x, AP.FHandle.y); end; procedure TBLMatrix2D.PostScale(const AX, AY: Double); begin FHandle.m00 := FHandle.m00 * AX; FHandle.m01 := FHandle.m01 * AY; FHandle.m10 := FHandle.m10 * AX; FHandle.m11 := FHandle.m11 * AY; FHandle.m20 := FHandle.m10 * AX; FHandle.m21 := FHandle.m11 * AY; end; procedure TBLMatrix2D.PostScale(const AXY: Double); begin PostScale(AXY, AXY); end; procedure TBLMatrix2D.PostScale(const AP: TBLPointI); begin PostScale(AP.FHandle.x, AP.FHandle.y); end; procedure TBLMatrix2D.PostSkew(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_POST_SKEW, @Data)); end; procedure TBLMatrix2D.PostSkew(const AP: TBLPoint); begin _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_POST_SKEW, @AP)); end; procedure TBLMatrix2D.PostTransform(const AMatrix: TBLMatrix2D); begin _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSFORM, @AMatrix)); end; procedure TBLMatrix2D.PostTranslate(const AX, AY: Double); begin FHandle.m20 := FHandle.m20 + AX; FHandle.m21 := FHandle.m21 + AY; end; procedure TBLMatrix2D.PostTranslate(const AP: TBLPoint); begin FHandle.m20 := FHandle.m20 + AP.FHandle.x; FHandle.m21 := FHandle.m21 + AP.FHandle.y; end; procedure TBLMatrix2D.PostTranslate(const AP: TBLPointI); begin FHandle.m20 := FHandle.m20 + AP.FHandle.x; FHandle.m21 := FHandle.m21 + AP.FHandle.y; end; procedure TBLMatrix2D.Reset(const AM00, AM01, AM10, AM11, AM20, AM21: Double); begin FHandle.m00 := AM00; FHandle.m01 := AM01; FHandle.m10 := AM10; FHandle.m11 := AM11; FHandle.m20 := AM20; FHandle.m21 := AM21; end; procedure TBLMatrix2D.Reset; begin FHandle.m00 := 1; FHandle.m01 := 0; FHandle.m10 := 0; FHandle.m11 := 1; FHandle.m20 := 0; FHandle.m21 := 0; end; procedure TBLMatrix2D.ResetToRotation(const AAngle: Double); begin _BLCheck(blMatrix2DSetRotation(@FHandle, AAngle, 0, 0)); end; procedure TBLMatrix2D.ResetToRotation(const AAngle, AX, AY: Double); begin _BLCheck(blMatrix2DSetRotation(@FHandle, AAngle, AX, AY)); end; procedure TBLMatrix2D.ResetToRotation(const AAngle: Double; const AP: TBLPoint); begin _BLCheck(blMatrix2DSetRotation(@FHandle, AAngle, AP.FHandle.x, AP.FHandle.y)); end; procedure TBLMatrix2D.ResetToScaling(const AX, AY: Double); begin Reset(AX, 0, 0, AY, 0, 0); end; procedure TBLMatrix2D.ResetToScaling(const AP: TBLPoint); begin Reset(AP.FHandle.x, 0, 0, AP.FHandle.y, 0, 0); end; procedure TBLMatrix2D.ResetToScaling(const AXY: Double); begin Reset(AXY, 0, 0, AXY, 0, 0); end; procedure TBLMatrix2D.ResetToScaling(const AP: TBLPointI); begin Reset(AP.FHandle.x, 0, 0, AP.FHandle.y, 0, 0); end; procedure TBLMatrix2D.ResetToSinCos(const ASin, ACos, ATranslateX, ATranslateY: Double); begin Reset(ACos, ASin, -ASin, ACos, ATranslateX, ATranslateY); end; procedure TBLMatrix2D.ResetToSinCos(const ASin, ACos: Double; const ATranslate: TBLPoint); begin Reset(ACos, ASin, -ASin, ACos, ATranslate.FHandle.x, ATranslate.FHandle.y); end; procedure TBLMatrix2D.ResetToSkewing(const AP: TBLPoint); begin _BLCheck(blMatrix2DSetSkewing(@FHandle, AP.FHandle.x, AP.FHandle.y)); end; procedure TBLMatrix2D.ResetToSkewing(const AX, AY: Double); begin _BLCheck(blMatrix2DSetSkewing(@FHandle, AX, AY)); end; procedure TBLMatrix2D.ResetToTranslation(const AP: TBLPointI); begin Reset(1, 0, 0, 1, AP.FHandle.x, AP.FHandle.y); end; procedure TBLMatrix2D.ResetToTranslation(const AP: TBLPoint); begin Reset(1, 0, 0, 1, AP.FHandle.x, AP.FHandle.y); end; procedure TBLMatrix2D.ResetToTranslation(const AX, AY: Double); begin Reset(1, 0, 0, 1, AX, AY); end; procedure TBLMatrix2D.Rotate(const AAngle: Double); begin _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_ROTATE, @AAngle)); end; procedure TBLMatrix2D.Rotate(const AAngle: Double; const AP: TBLPoint); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLMatrix2D.Rotate(const AAngle, AX, AY: Double); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AX; Data[2] := AY; _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLMatrix2D.Scale(const AXY: Double); begin FHandle.m00 := FHandle.m00 * AXY; FHandle.m01 := FHandle.m01 * AXY; FHandle.m10 := FHandle.m10 * AXY; FHandle.m11 := FHandle.m11 * AXY; end; procedure TBLMatrix2D.Scale(const AP: TBLPointI); begin Scale(AP.FHandle.x, AP.FHandle.y); end; procedure TBLMatrix2D.Scale(const AP: TBLPoint); begin Scale(AP.FHandle.x, AP.FHandle.y); end; procedure TBLMatrix2D.Scale(const AX, AY: Double); begin FHandle.m00 := FHandle.m00 * AX; FHandle.m01 := FHandle.m01 * AX; FHandle.m10 := FHandle.m10 * AY; FHandle.m11 := FHandle.m11 * AY; end; procedure TBLMatrix2D.SetElement(const AIndex: TBLMatrix2DValue; const AValue: Double); begin FHandle.m[Ord(AIndex)] := AValue; end; procedure TBLMatrix2D.Skew(const AP: TBLPoint); begin _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_SKEW, @AP)); end; procedure TBLMatrix2D.Skew(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_SKEW, @Data)); end; procedure TBLMatrix2D.Transform(const AMatrix: TBLMatrix2D); begin _BLCheck(blMatrix2DApplyOp(@FHandle, BL_MATRIX2D_OP_TRANSFORM, @AMatrix)); end; procedure TBLMatrix2D.Translate(const AX, AY: Double); begin FHandle.m20 := FHandle.m20 + (AX * FHandle.m00) + (AY * FHandle.m10); FHandle.m21 := FHandle.m21 + (AX * FHandle.m01) + (AY * FHandle.m11); end; procedure TBLMatrix2D.Translate(const AP: TBLPoint); begin Translate(AP.FHandle.x, AP.FHandle.y); end; procedure TBLMatrix2D.Translate(const AP: TBLPointI); begin Translate(AP.FHandle.x, AP.FHandle.y); end; {$ENDREGION 'Matrix'} {$REGION 'Random'} { TBLRandom } class operator TBLRandom.Equal(const ALeft, ARight: TBLRandom): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLRandom.Equals(const AOther: TBLRandom): Boolean; begin Result := (FHandle.data[0] = AOther.FHandle.data[0]) and (FHandle.data[1] = AOther.FHandle.data[1]); end; function TBLRandom.NextDouble: Double; begin Result := blRandomNextDouble(@FHandle); end; function TBLRandom.NextUInt32: UInt32; begin Result := blRandomNextUInt32(@FHandle); end; function TBLRandom.NextUInt64: UInt64; begin Result := blRandomNextUInt64(@FHandle); end; class operator TBLRandom.NotEqual(const ALeft, ARight: TBLRandom): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLRandom.Reset(const ASeed: UInt64); begin blRandomReset(@FHandle, ASeed); end; {$ENDREGION 'Random'} {$REGION 'Gradient'} { TBLGradientStop } function BLGradientStop(const AOffset: Double; const ARgba: TBLRgba32): TBLGradientStop; overload; inline; begin Result.Reset(AOffset, ARgba); end; function BLGradientStop(const AOffset: Double; const ARgba: TBLRgba64): TBLGradientStop; overload; inline; begin Result.Reset(AOffset, ARgba); end; class operator TBLGradientStop.Equal(const ALeft, ARight: TBLGradientStop): Boolean; begin Result := (ALeft.FHandle.offset = ARight.FHandle.offset) and (ALeft.FHandle.rgba.value = ARight.FHandle.rgba.value); end; function TBLGradientStop.Equals(const AOther: TBLGradientStop): Boolean; begin Result := (Self = AOther); end; function TBLGradientStop.GetRgba: TBLRgba64; begin Result.FHandle.value := FHandle.rgba.value; end; class operator TBLGradientStop.NotEqual(const ALeft, ARight: TBLGradientStop): Boolean; begin Result := not (ALeft = ARight); end; procedure TBLGradientStop.Reset(const AOffset: Double; const ARgba: TBLRgba64); begin FHandle.offset := AOffset; FHandle.rgba.value := ARgba.FHandle.value; end; procedure TBLGradientStop.Reset(const AOffset: Double; const ARgba: TBLRgba32); begin FHandle.offset := AOffset; TBLRgba64(FHandle.rgba).Reset(ARgba); end; procedure TBLGradientStop.Reset; begin FHandle.offset := 0; FHandle.rgba.value := 0; end; procedure TBLGradientStop.SetRgba(const AValue: TBLRgba64); begin FHandle.rgba.value := AValue.FHandle.value; end; { TBLLinearGradientValues } function BLLinearGradientValues(const AX0, AY0, AX1, AY1: Double): TBLLinearGradientValues; inline; begin Result.Reset(AX0, AY0, AX1, AY1); end; procedure TBLLinearGradientValues.Reset(const AX0, AY0, AX1, AY1: Double); begin FHandle.x0 := AX0; FHandle.y0 := AY0; FHandle.x1 := AX1; FHandle.y1 := AY1; end; procedure TBLLinearGradientValues.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; { TBLRadialGradientValues } function BLRadialGradientValues(const AX0, AY0, AX1, AY1, AR0: Double): TBLRadialGradientValues; inline; begin Result.Reset(AX0, AY0, AX1, AY1, AR0); end; procedure TBLRadialGradientValues.Reset(const AX0, AY0, AX1, AY1, AR0: Double); begin FHandle.x0 := AX0; FHandle.y0 := AY0; FHandle.x1 := AX1; FHandle.y1 := AY1; FHandle.r0 := AR0; end; procedure TBLRadialGradientValues.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; { TBLConicalGradientValues } function BLConicalGradientValues(const AX0, AY0, AAngle: Double): TBLConicalGradientValues; inline; begin Result.Reset(AX0, AY0, AAngle); end; procedure TBLConicalGradientValues.Reset(const AX0, AY0, AAngle: Double); begin FHandle.x0 := AX0; FHandle.y0 := AY0; FHandle.angle := AAngle; end; procedure TBLConicalGradientValues.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; { TBLGradient } procedure TBLGradient.AddStop(const AOffset: Double; const ARgba: TBLRgba64); begin _BLCheck(blGradientAddStopRgba64(@FHandle, AOffset, ARgba.FHandle.value)); end; procedure TBLGradient.AddStop(const AOffset: Double; const ARgba: TBLRgba32); begin _BLCheck(blGradientAddStopRgba32(@FHandle, AOffset, ARgba.FHandle.value)); end; constructor TBLGradient.Create; begin inherited; blGradientInit(@FHandle); end; constructor TBLGradient.Create(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray); begin inherited Create; _BLCheck(blGradientInitAs(@FHandle, BL_GRADIENT_TYPE_RADIAL, @AValues.FHandle, Ord(AExtendMode), Pointer(AStops), Length(AStops), nil)); end; constructor TBLGradient.Create(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray); begin inherited Create; _BLCheck(blGradientInitAs(@FHandle, BL_GRADIENT_TYPE_LINEAR, @AValues.FHandle, Ord(AExtendMode), Pointer(AStops), Length(AStops), nil)); end; constructor TBLGradient.Create(const AType: TBLGradientType; const AValues: PDouble); begin inherited Create; _BLCheck(blGradientInitAs(@FHandle, Ord(AType), AValues, BL_EXTEND_MODE_PAD, nil, 0, nil)); end; constructor TBLGradient.Create(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray); begin inherited Create; _BLCheck(blGradientInitAs(@FHandle, BL_GRADIENT_TYPE_CONICAL, @AValues.FHandle, Ord(AExtendMode), Pointer(AStops), Length(AStops), nil)); end; constructor TBLGradient.Create(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); begin inherited Create; _BLCheck(blGradientInitAs(@FHandle, BL_GRADIENT_TYPE_CONICAL, @AValues.FHandle, Ord(AExtendMode), Pointer(AStops), Length(AStops), @AMatrix)); end; constructor TBLGradient.Create(const AHandle: BLGradientCore; const AIsReference: Boolean); begin inherited Create; FHandle := AHandle; FIsReference := AIsReference; end; constructor TBLGradient.Create(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); begin inherited Create; _BLCheck(blGradientInitAs(@FHandle, BL_GRADIENT_TYPE_RADIAL, @AValues.FHandle, Ord(AExtendMode), Pointer(AStops), Length(AStops), @AMatrix)); end; constructor TBLGradient.Create(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); begin inherited Create; _BLCheck(blGradientInitAs(@FHandle, BL_GRADIENT_TYPE_LINEAR, @AValues.FHandle, Ord(AExtendMode), Pointer(AStops), Length(AStops), @AMatrix)); end; destructor TBLGradient.Destroy; begin if (not FIsReference) then blGradientDestroy(@FHandle); inherited; end; function TBLGradient.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLGradient) then Result := blGradientEquals(@FHandle, @TBLGradient(Obj).FHandle) else Result := False; end; function TBLGradient.Equals(const AOther: IBLGradient): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := blGradientEquals(@FHandle, AOther.Handle); end; function TBLGradient.GetAllStops: PBLGradientStop; begin Result := PBLGradientStop(FHandle.impl.stops.stops); end; function TBLGradient.GetAngle: Double; begin Result := FHandle.impl.values[BL_GRADIENT_VALUE_CONICAL_ANGLE]; end; function TBLGradient.GetCapacity: Integer; begin Result := FHandle.impl.capacity; end; function TBLGradient.GetConical: TBLConicalGradientValues; begin Result.FHandle := FHandle.impl.conical; end; function TBLGradient.GetExtendMode: TBLExtendMode; begin Result := TBLExtendMode(FHandle.impl.extendMode); end; function TBLGradient.GetGradientType: TBLGradientType; begin Result := TBLGradientType(FHandle.impl.gradientType); end; function TBLGradient.GetHandle: PBLGradientCore; begin Result := @FHandle; end; function TBLGradient.GetHasMatrix: Boolean; begin Result := ((FHandle.impl.matrixType and BL_MATRIX2D_TYPE_IDENTITY) <> 0); end; function TBLGradient.GetIsEmpty: Boolean; begin Result := (FHandle.impl.stops.size = 0); end; function TBLGradient.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLGradient.GetLinear: TBLLinearGradientValues; begin Result.FHandle := FHandle.impl.linear; end; function TBLGradient.GetMatrix: TBLMatrix2D; begin Result.FHandle := FHandle.impl.matrix; end; function TBLGradient.GetMatrixType: TBLMatrix2DType; begin Result := TBLMatrix2DType(FHandle.impl.matrixType); end; function TBLGradient.GetR0: Double; begin Result := FHandle.impl.values[BL_GRADIENT_VALUE_RADIAL_R0]; end; function TBLGradient.GetRadial: TBLRadialGradientValues; begin Result.FHandle := FHandle.impl.radial; end; function TBLGradient.GetSize: Integer; begin Result := FHandle.impl.stops.size; end; function TBLGradient.GetStop(const AIndex: Integer): TBLGradientStop; begin Assert(Cardinal(AIndex) < FHandle.impl.stops.size); Result := TBLGradientStop(FHandle.impl.stops.stops[AIndex]); end; function TBLGradient.GetValue(const AIndex: TBLGradientValue): Double; begin Result := FHandle.impl.values[Ord(AIndex)]; end; function TBLGradient.GetX0: Double; begin Result := FHandle.impl.values[BL_GRADIENT_VALUE_COMMON_X0]; end; function TBLGradient.GetX1: Double; begin Result := FHandle.impl.values[BL_GRADIENT_VALUE_COMMON_X1]; end; function TBLGradient.GetY0: Double; begin Result := FHandle.impl.values[BL_GRADIENT_VALUE_COMMON_Y0]; end; function TBLGradient.GetY1: Double; begin Result := FHandle.impl.values[BL_GRADIENT_VALUE_COMMON_Y1]; end; function TBLGradient.IndexOfStop(const AOffset: Double): Integer; begin Result := blGradientIndexOfStop(@FHandle, AOffset); end; procedure TBLGradient.Initialize(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); begin _BLCheck(blGradientCreate(@FHandle, BL_GRADIENT_TYPE_CONICAL, @AValues, Ord(AExtendMode), Pointer(AStops), Length(AStops), @AMatrix)); end; procedure TBLGradient.Initialize(const AValues: TBLConicalGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray); begin _BLCheck(blGradientCreate(@FHandle, BL_GRADIENT_TYPE_CONICAL, @AValues, Ord(AExtendMode), Pointer(AStops), Length(AStops), nil)); end; procedure TBLGradient.Initialize(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray); begin _BLCheck(blGradientCreate(@FHandle, BL_GRADIENT_TYPE_RADIAL, @AValues, Ord(AExtendMode), Pointer(AStops), Length(AStops), nil)); end; procedure TBLGradient.Initialize(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray); begin _BLCheck(blGradientCreate(@FHandle, BL_GRADIENT_TYPE_LINEAR, @AValues, Ord(AExtendMode), Pointer(AStops), Length(AStops), nil)); end; procedure TBLGradient.Initialize(const AValues: TBLRadialGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); begin _BLCheck(blGradientCreate(@FHandle, BL_GRADIENT_TYPE_RADIAL, @AValues, Ord(AExtendMode), Pointer(AStops), Length(AStops), @AMatrix)); end; procedure TBLGradient.Initialize(const AValues: TBLLinearGradientValues; const AExtendMode: TBLExtendMode; const AStops: TArray; const AMatrix: TBLMatrix2D); begin _BLCheck(blGradientCreate(@FHandle, BL_GRADIENT_TYPE_LINEAR, @AValues, Ord(AExtendMode), Pointer(AStops), Length(AStops), @AMatrix)); end; procedure TBLGradient.PostRotate(const AAngle: Double); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE, @AAngle)); end; procedure TBLGradient.PostRotate(const AAngle, AX, AY: Double); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AX; Data[2] := AY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLGradient.PostRotate(const AAngle: Double; const AP: TBLPointI); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLGradient.PostRotate(const AAngle: Double; const AP: TBLPoint); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLGradient.PostScale(const AP: TBLPoint); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @AP)); end; procedure TBLGradient.PostScale(const AP: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := AP.FHandle.x; Data[1] := AP.FHandle.y; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @Data)); end; procedure TBLGradient.PostScale(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @Data)); end; procedure TBLGradient.PostScale(const AXY: Double); var Data: array [0..1] of Double; begin Data[0] := AXY; Data[1] := AXY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @Data)); end; procedure TBLGradient.PostSkew(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SKEW, @Data)); end; procedure TBLGradient.PostSkew(const AP: TBLPoint); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SKEW, @AP)); end; procedure TBLGradient.PostTransform(const AMatrix: TBLMatrix2D); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSFORM, @AMatrix)); end; procedure TBLGradient.PostTranslate(const AP: TBLPoint); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSLATE, @AP)); end; procedure TBLGradient.PostTranslate(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSLATE, @Data)); end; procedure TBLGradient.PostTranslate(const AP: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := AP.FHandle.x; Data[1] := AP.FHandle.y; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSLATE, @Data)); end; procedure TBLGradient.RemoveStop(const AIndex: Integer); begin _BLCheck(blGradientRemoveStop(@FHandle, AIndex)); end; procedure TBLGradient.RemoveStopByOffset(const AOffset: Double; const AAll: Boolean); begin _BLCheck(blGradientRemoveStopByOffset(@FHandle, AOffset, Ord(AAll))); end; procedure TBLGradient.RemoveStops(const ARange: TBLRange); begin _BLCheck(blGradientRemoveStops(@FHandle, ARange.FHandle.start, ARange.FHandle.&end)); end; procedure TBLGradient.RemoveStopsByOffset(const AOffsetMin, AOffsetMax: Double); begin _BLCheck(blGradientRemoveStopsFromTo(@FHandle, AOffsetMin, AOffsetMax)); end; procedure TBLGradient.ReplaceStop(const AIndex: Integer; const AOffset: Double; const ARgba: TBLRgba64); begin _BLCheck(blGradientReplaceStopRgba64(@FHandle, AIndex, AOffset, ARgba.FHandle.value)); end; procedure TBLGradient.ReplaceStop(const AIndex: Integer; const AOffset: Double; const ARgba: TBLRgba32); begin _BLCheck(blGradientReplaceStopRgba32(@FHandle, AIndex, AOffset, ARgba.FHandle.value)); end; procedure TBLGradient.Reserve(const ACount: Integer); begin _BLCheck(blGradientReserve(@FHandle, ACount)); end; procedure TBLGradient.Reset; begin _BLCheck(blGradientReset(@FHandle)); end; procedure TBLGradient.ResetExtendMode; begin _BLCheck(blGradientSetExtendMode(@FHandle, BL_EXTEND_MODE_PAD)); end; procedure TBLGradient.ResetMatrix; begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_RESET, nil)); end; procedure TBLGradient.ResetStops; begin _BLCheck(blGradientResetStops(@FHandle)); end; procedure TBLGradient.Rotate(const AAngle: Double; const AP: TBLPoint); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLGradient.Rotate(const AAngle, AX, AY: Double); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AX; Data[2] := AY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLGradient.Rotate(const AAngle: Double); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE, @AAngle)); end; procedure TBLGradient.Rotate(const AAngle: Double; const AP: TBLPointI); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLGradient.Scale(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @Data)); end; procedure TBLGradient.Scale(const AXY: Double); var Data: array [0..1] of Double; begin Data[0] := AXY; Data[1] := AXY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @Data)); end; procedure TBLGradient.Scale(const AP: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := AP.FHandle.x; Data[1] := AP.FHandle.y; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @Data)); end; procedure TBLGradient.Scale(const AP: TBLPoint); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @AP)); end; procedure TBLGradient.SetAngle(const AValue: Double); begin _BLCheck(blGradientSetValue(@FHandle, BL_GRADIENT_VALUE_CONICAL_ANGLE, AValue)); end; procedure TBLGradient.SetConical(const AValue: TBLConicalGradientValues); begin _BLCheck(blGradientSetValues(@FHandle, 0, @AValue, SizeOf(AValue) div SizeOf(Double))); end; procedure TBLGradient.SetExtendMode(const AValue: TBLExtendMode); begin _BLCheck(blGradientSetExtendMode(@FHandle, Ord(AValue))); end; procedure TBLGradient.SetGradientType(const AValue: TBLGradientType); begin _BLCheck(blGradientSetType(@FHandle, Ord(AValue))); end; procedure TBLGradient.SetLinear(const AValue: TBLLinearGradientValues); begin _BLCheck(blGradientSetValues(@FHandle, 0, @AValue, SizeOf(AValue) div SizeOf(Double))); end; procedure TBLGradient.SetMatrix(const AValue: TBLMatrix2D); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ASSIGN, @AValue)); end; procedure TBLGradient.SetR0(const AValue: Double); begin _BLCheck(blGradientSetValue(@FHandle, BL_GRADIENT_VALUE_RADIAL_R0, AValue)); end; procedure TBLGradient.SetRadial(const AValue: TBLRadialGradientValues); begin _BLCheck(blGradientSetValues(@FHandle, 0, @AValue, SizeOf(AValue) div SizeOf(Double))); end; procedure TBLGradient.SetStop(const AIndex: Integer; const AValue: TBLGradientStop); begin _BLCheck(blGradientReplaceStopRgba64(@FHandle, AIndex, AValue.FHandle.offset, AValue.FHandle.rgba.value)); end; procedure TBLGradient.SetStops(const AStops: TArray); begin _BLCheck(blGradientAssignStops(@FHandle, Pointer(AStops), Length(AStops))); end; procedure TBLGradient.SetValue(const AIndex: TBLGradientValue; const AValue: Double); begin _BLCheck(blGradientSetValue(@FHandle, Ord(AIndex), AValue)); end; procedure TBLGradient.SetValues(const AValues: TBLLinearGradientValues); begin _BLCheck(blGradientSetValues(@FHandle, 0, @AValues, SizeOf(TBLLinearGradientValues) div SizeOf(Double))); end; procedure TBLGradient.SetValues(const AValues: TBLRadialGradientValues); begin _BLCheck(blGradientSetValues(@FHandle, 0, @AValues, SizeOf(TBLRadialGradientValues) div SizeOf(Double))); end; procedure TBLGradient.SetValues(const AValues: TBLConicalGradientValues); begin _BLCheck(blGradientSetValues(@FHandle, 0, @AValues, SizeOf(TBLConicalGradientValues) div SizeOf(Double))); end; procedure TBLGradient.SetValues(const AIndex: TBLGradientValue; const AValues: TArray); begin _BLCheck(blGradientSetValues(@FHandle, Ord(AIndex), Pointer(AValues), Length(AValues))); end; procedure TBLGradient.SetX0(const AValue: Double); begin _BLCheck(blGradientSetValue(@FHandle, BL_GRADIENT_VALUE_COMMON_X0, AValue)); end; procedure TBLGradient.SetX1(const AValue: Double); begin _BLCheck(blGradientSetValue(@FHandle, BL_GRADIENT_VALUE_COMMON_X1, AValue)); end; procedure TBLGradient.SetY0(const AValue: Double); begin _BLCheck(blGradientSetValue(@FHandle, BL_GRADIENT_VALUE_COMMON_Y0, AValue)); end; procedure TBLGradient.SetY1(const AValue: Double); begin _BLCheck(blGradientSetValue(@FHandle, BL_GRADIENT_VALUE_COMMON_Y1, AValue)); end; procedure TBLGradient.Shrink; begin _BLCheck(blGradientShrink(@FHandle)); end; procedure TBLGradient.Skew(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SKEW, @Data)); end; procedure TBLGradient.Skew(const AP: TBLPoint); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SKEW, @AP)); end; procedure TBLGradient.Transform(const AMatrix: TBLMatrix2D); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSFORM, @AMatrix)); end; procedure TBLGradient.Translate(const AP: TBLPoint); begin _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSLATE, @AP)); end; procedure TBLGradient.Translate(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSLATE, @Data)); end; procedure TBLGradient.Translate(const AP: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := AP.FHandle.x; Data[1] := AP.FHandle.y; _BLCheck(blGradientApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSLATE, @Data)); end; {$ENDREGION 'Gradient'} {$REGION 'Region'} { TBLRegion } procedure TBLRegion.Assign(const ABoxes: PBLBoxI; const ACount: Integer); begin _BLCheck(blRegionAssignBoxIArray(@FHandle, Pointer(ABoxes), ACount)); end; procedure TBLRegion.Assign(const ABoxes: TArray); begin _BLCheck(blRegionAssignBoxIArray(@FHandle, Pointer(ABoxes), Length(ABoxes))); end; procedure TBLRegion.Assign(const ABox: TBLBoxI); begin _BLCheck(blRegionAssignBoxI(@FHandle, @ABox)); end; procedure TBLRegion.Assign(const ARects: PBLRectI; const ACount: Integer); begin _BLCheck(blRegionAssignRectIArray(@FHandle, Pointer(ARects), ACount)); end; procedure TBLRegion.Assign(const ARect: TBLRectI); begin _BLCheck(blRegionAssignRectI(@FHandle, @ARect)); end; procedure TBLRegion.Assign(const ARects: TArray); begin _BLCheck(blRegionAssignRectIArray(@FHandle, Pointer(ARects), Length(ARects))); end; procedure TBLRegion.Clear; begin _BLCheck(blRegionClear(@FHandle)); end; function TBLRegion.Clone: IBLRegion; begin Result := TBLRegion.Create; _BLCheck(blRegionAssignDeep(Result.Handle, @FHandle)); end; class function TBLRegion.Combine(const AA, AB: IBLRegion; const ABooleanOp: TBLBooleanOp): IBLRegion; begin Result := TBLRegion.Create; if (AA <> nil) and (AB <> nil) then _BLCheck(blRegionCombine(Result.Handle, AA.Handle, AB.Handle, Ord(ABooleanOp))); end; procedure TBLRegion.Combine(const ABox: TBLBoxI; const ABooleanOp: TBLBooleanOp); begin _BLCheck(blRegionCombineRB(@FHandle, @FHandle, @ABox, Ord(ABooleanOp))); end; procedure TBLRegion.Combine(const ARegion: IBLRegion; const ABooleanOp: TBLBooleanOp); begin if (ARegion <> nil) then _BLCheck(blRegionCombine(@FHandle, @FHandle, ARegion.Handle, Ord(ABooleanOp))); end; class function TBLRegion.Combine(const AA, AB: TBLBoxI; const ABooleanOp: TBLBooleanOp): IBLRegion; begin Result := TBLRegion.Create; _BLCheck(blRegionCombineBB(Result.Handle, @AA, @AB, Ord(ABooleanOp))); end; class function TBLRegion.Combine(const AA: TBLBoxI; const AB: IBLRegion; const ABooleanOp: TBLBooleanOp): IBLRegion; begin Result := TBLRegion.Create; if (AB <> nil) then _BLCheck(blRegionCombineBR(Result.Handle, @AA, AB.Handle, Ord(ABooleanOp))); end; class function TBLRegion.Combine(const AA: IBLRegion; const AB: TBLBoxI; const ABooleanOp: TBLBooleanOp): IBLRegion; begin Result := TBLRegion.Create; if (AA <> nil) then _BLCheck(blRegionCombineRB(Result.Handle, AA.Handle, @AB, Ord(ABooleanOp))); end; constructor TBLRegion.Create; begin inherited; blRegionInit(@FHandle); end; destructor TBLRegion.Destroy; begin blRegionDestroy(@FHandle); inherited; end; function TBLRegion.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLRegion) then Result := blRegionEquals(@FHandle, @TBLRegion(Obj).FHandle) else Result := False; end; function TBLRegion.Equals(const AOther: IBLRegion): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := blRegionEquals(@FHandle, AOther.Handle); end; function TBLRegion.GetBoundingBox: TBLBoxI; begin Result.FHandle := FHandle.impl.boundingBox; end; function TBLRegion.GetCapacity: Integer; begin Result := FHandle.impl.capacity; end; function TBLRegion.GetData: PBLBoxI; begin Result := Pointer(FHandle.impl.data.data); end; function TBLRegion.GetDataEnd: PBLBoxI; begin Result := Pointer(FHandle.impl.data.data); Inc(Result, FHandle.impl.data.size); end; function TBLRegion.GetHandle: PBLRegionCore; begin Result := @FHandle; end; function TBLRegion.GetIsComplex: Boolean; begin Result := (FHandle.impl.data.size > 1); end; function TBLRegion.GetIsEmpty: Boolean; begin Result := (FHandle.impl.data.size = 0); end; function TBLRegion.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLRegion.GetIsRect: Boolean; begin Result := (FHandle.impl.data.size = 1); end; function TBLRegion.GetRegionType: TBLRegionType; begin Result := TBLRegionType(Min(FHandle.impl.data.size, BL_REGION_TYPE_COMPLEX)); end; function TBLRegion.GetSize: Integer; begin Result := FHandle.impl.data.size; end; function TBLRegion.GetView: TBLRegionView; begin Result.FHandle := BLArrayView(FHandle.impl.data.view); end; function TBLRegion.HitTest(const ABox: TBLBoxI): TBLHitTest; begin Result := TBLHitTest(blRegionHitTestBoxI(@FHandle, @ABox)); end; function TBLRegion.HitTest(const APt: TBLPointI): TBLHitTest; begin Result := TBLHitTest(blRegionHitTest(@FHandle, @APt)); end; class function TBLRegion.IntersectAndClip(const AA, AB: IBLRegion; const AClipBox: TBLBoxI): IBLRegion; begin Result := TBLRegion.Create; if Assigned(AA) and Assigned(AB) then _BLCheck(blRegionIntersectAndClip(Result.Handle, AA.Handle, AB.Handle, @AClipBox)); end; procedure TBLRegion.IntersectAndClip(const AR: IBLRegion; const AClipBox: TBLBoxI); begin if Assigned(AR) then _BLCheck(blRegionIntersectAndClip(@FHandle, @FHandle, AR.Handle, @AClipBox)); end; procedure TBLRegion.Reserve(const ACount: Integer); begin _BLCheck(blRegionReserve(@FHandle, ACount)); end; procedure TBLRegion.Reset; begin _BLCheck(blRegionReset(@FHandle)); end; procedure TBLRegion.Shrink; begin _BLCheck(blRegionShrink(@FHandle)); end; procedure TBLRegion.Translate(const APt: TBLPointI); begin _BLCheck(blRegionTranslate(@FHandle, @FHandle, @APt)); end; class function TBLRegion.Translate(const AR: IBLRegion; const APt: TBLPointI): IBLRegion; begin Result := TBLRegion.Create; if Assigned(AR) then _BLCheck(blRegionTranslate(Result.Handle, AR.Handle, @APt)); end; class function TBLRegion.TranslateAndClip(const AR: IBLRegion; const APt: TBLPointI; const AClipBox: TBLBoxI): IBLRegion; begin Result := TBLRegion.Create; if Assigned(AR) then _BLCheck(blRegionTranslateAndClip(Result.Handle, AR.Handle, @APt, @AClipBox)); end; procedure TBLRegion.TranslateAndClip(const APt: TBLPointI; const AClipBox: TBLBoxI); begin _BLCheck(blRegionTranslateAndClip(@FHandle, @FHandle, @APt, @AClipBox)); end; {$ENDREGION 'Region'} {$REGION 'Path'} { TBLApproximationOptions } class constructor TBLApproximationOptions.Create; begin FillChar(FDefault, SizeOf(FDefault), 0); FDefault.flattenTolerance := 0.2; FDefault.simplifyTolerance := 0.05; FDefault.offsetParameter := 0.414213562; end; class function TBLApproximationOptions.GetDefault: TBLApproximationOptions; begin Result.FHandle := FDefault; end; function TBLApproximationOptions.GetFlattenMode: TBLFlattenMode; begin Result := TBLFlattenMode(FHandle.flattenMode); end; function TBLApproximationOptions.GetOffsetMode: TBLOffsetMode; begin Result := TBLOffsetMode(FHandle.offsetMode); end; procedure TBLApproximationOptions.SetFlattenMode(const AValue: TBLFlattenMode); begin FHandle.flattenMode := Ord(AValue); end; procedure TBLApproximationOptions.SetOffsetMode(const AValue: TBLOffsetMode); begin FHandle.offsetMode := Ord(AValue); end; { TBLStrokeOptions } function TBLStrokeOptions.GetDashArray: TArray; begin Result := TBLUtils.BLArrayToArray(FHandle.dashArray); end; function TBLStrokeOptions.GetEndCap: TBLStrokeCap; begin Result := TBLStrokeCap(FHandle.options.endCap); end; function TBLStrokeOptions.GetJoin: TBLStrokeJoin; begin Result := TBLStrokeJoin(FHandle.options.join); end; function TBLStrokeOptions.GetStartCap: TBLStrokeCap; begin Result := TBLStrokeCap(FHandle.options.startCap); end; function TBLStrokeOptions.GetTransformOrder: TBLStrokeTransformOrder; begin Result := TBLStrokeTransformOrder(FHandle.options.transformOrder); end; procedure TBLStrokeOptions.Reset; begin if (FScope <> nil) then blStrokeOptionsReset(@FHandle) else begin blStrokeOptionsInit(@FHandle); FScope := TScope.Create(@FHandle); end; end; procedure TBLStrokeOptions.SetCaps(const AStartCap, AEndCap: TBLStrokeCap); begin FHandle.options.startCap := Ord(AStartCap); FHandle.options.endCap := Ord(AEndCap); end; procedure TBLStrokeOptions.SetCaps(const ACap: TBLStrokeCap); begin FHandle.options.startCap := Ord(ACap); FHandle.options.endCap := Ord(ACap); end; procedure TBLStrokeOptions.SetDashArray(const AValue: TArray); var Value: IBLArray; begin blArrayReset(@FHandle.dashArray); Value := TBLUtils.ArrayToBLArray(AValue); Value.RevokeOwnership; FHandle.dashArray := Value.Handle^; end; procedure TBLStrokeOptions.SetEndCap(const AValue: TBLStrokeCap); begin FHandle.options.endCap := Ord(AValue); end; procedure TBLStrokeOptions.SetJoin(const AValue: TBLStrokeJoin); begin FHandle.options.join := Ord(AValue); end; procedure TBLStrokeOptions.SetStartCap(const AValue: TBLStrokeCap); begin FHandle.options.startCap := Ord(AValue); end; procedure TBLStrokeOptions.SetTransformOrder( const AValue: TBLStrokeTransformOrder); begin FHandle.options.transformOrder := Ord(AValue); end; { TBLStrokeOptions.TScope } constructor TBLStrokeOptions.TScope.Create(const AHandle: PBLStrokeOptionsCore); begin inherited Create; FHandle := AHandle; end; destructor TBLStrokeOptions.TScope.Destroy; begin blStrokeOptionsDestroy(FHandle); inherited; end; { TBLPathView } function BLPathView(const ACommands: PBLPathCmd; const AVertices: PBLPoint; const ACount: Integer): TBLPathView; inline; begin Result.Reset(ACommands, AVertices, ACount); end; function TBLPathView.GetCommands: PBLPathCmd; begin Result := Pointer(FHandle.commandData); end; function TBLPathView.GetCount: Integer; begin Result := FHandle.size; end; function TBLPathView.GetVertices: PBLPoint; begin Result := Pointer(FHandle.vertexData); end; procedure TBLPathView.Reset(const ACommands: PBLPathCmd; const AVertices: PBLPoint; const ACount: Integer); begin FHandle.commandData := Pointer(ACommands); FHandle.vertexData := Pointer(AVertices); FHandle.size := ACount; end; procedure TBLPathView.Reset; begin FHandle.commandData := nil; FHandle.vertexData := nil; FHandle.size := 0; end; { TBLPath } procedure TBLPath.AddArc(const AArc: TBLArc; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARC, @AArc, nil, Ord(ADirection))); end; procedure TBLPath.AddArc(const AArc: TBLArc; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARC, @AArc, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddBox(const ABox: TBLBoxI; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddBoxI(@FHandle, @ABox, Ord(ADirection))); end; procedure TBLPath.AddBox(const ABox: TBLBox; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddBoxD(@FHandle, @ABox, Ord(ADirection))); end; procedure TBLPath.AddBox(const AX0, AY0, AX1, AY1: Double; const ADirection: TBLGeometryDirection); var Box: TBLBox; begin Box.Reset(AX0, AY0, AX1, AY1); _BLCheck(blPathAddBoxD(@FHandle, @Box, Ord(ADirection))); end; procedure TBLPath.AddBoxArray(const ABoxes: TBLArrayView; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @ABoxes.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddBoxArray(const ABoxes: PBLBoxI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(ABoxes, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @View.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddBoxArray(const ABoxes: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @ABoxes.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddBoxArray(const ABoxes: PBLBoxI; const ACount: Integer; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(ABoxes, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @View.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddBoxArray(const ABoxes: PBLBox; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(ABoxes, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @View.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddBoxArray(const ABoxes: PBLBox; const ACount: Integer; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(ABoxes, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @View.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddBoxArray(const ABoxes: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @ABoxes.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddBoxArray(const ABoxes: TBLArrayView; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @ABoxes.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddChord(const AChord: TBLArc; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_CHORD, @AChord, nil, Ord(ADirection))); end; procedure TBLPath.AddChord(const AChord: TBLArc; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_CHORD, @AChord, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddCircle(const ACircle: TBLCircle; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_CIRCLE, @ACircle, nil, Ord(ADirection))); end; procedure TBLPath.AddCircle(const ACircle: TBLCircle; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_CIRCLE, @ACircle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddEllipse(const AEllipse: TBLEllipse; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ELLIPSE, @AEllipse, nil, Ord(ADirection))); end; procedure TBLPath.AddEllipse(const AEllipse: TBLEllipse; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ELLIPSE, @AEllipse, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddGeometry(const AGeometryType: TBLGeometryType; const AGeometryData: Pointer; const AMatrix: PBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, Ord(AGeometryType), AGeometryData, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddLine(const ALine: TBLLine; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_LINE, @ALine, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddLine(const ALine: TBLLine; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_LINE, @ALine, nil, Ord(ADirection))); end; procedure TBLPath.AddPath(const APath: IBLPath; const ARange: TBLRange); begin if (APath <> nil) then _BLCheck(blPathAddPath(@FHandle, APath.Handle, @ARange)); end; procedure TBLPath.AddPath(const APath: IBLPath); begin if (APath <> nil) then _BLCheck(blPathAddPath(@FHandle, APath.Handle, nil)); end; procedure TBLPath.AddPath(const APath: IBLPath; const ATranslate: TBLPoint); begin if (APath <> nil) then _BLCheck(blPathAddTranslatedPath(@FHandle, APath.Handle, nil, @ATranslate)); end; procedure TBLPath.AddPath(const APath: IBLPath; const ARange: TBLRange; const AMatrix: TBLMatrix2D); begin if (APath <> nil) then _BLCheck(blPathAddTransformedPath(@FHandle, APath.Handle, @ARange, @AMatrix)); end; procedure TBLPath.AddPath(const APath: IBLPath; const AMatrix: TBLMatrix2D); begin if (APath <> nil) then _BLCheck(blPathAddTransformedPath(@FHandle, APath.Handle, nil, @AMatrix)); end; procedure TBLPath.AddPath(const APath: IBLPath; const ARange: TBLRange; const ATranslate: TBLPoint); begin if (APath <> nil) then _BLCheck(blPathAddTranslatedPath(@FHandle, APath.Handle, @ARange, @ATranslate)); end; procedure TBLPath.AddPie(const APie: TBLArc; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_PIE, @APie, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddPie(const APie: TBLArc; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_PIE, @APie, nil, Ord(ADirection))); end; procedure TBLPath.AddPolygon(const APolygon: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @APolygon.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddPolygon(const APolygon: TBLArrayView; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @APolygon.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddPolygon(const APolygon: PBLPoint; const ACount: Integer; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(APolygon, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @View.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddPolygon(const APolygon: PBLPoint; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(APolygon, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @View.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddPolygon(const APolygon: TBLArrayView; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @APolygon.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddPolygon(const APolygon: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @APolygon.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddPolygon(const APolygon: PBLPointI; const ACount: Integer; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(APolygon, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @View.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddPolygon(const APolygon: PBLPointI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(APolygon, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @View.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddPolyline(const APolyline: TBLArrayView; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINED, @APolyline.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddPolyline(const APolyline: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINED, @APolyline.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddPolyline(const APolyline: PBLPoint; const ACount: Integer; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(APolyline, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINED, @View.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddPolyline(const APolyline: PBLPoint; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(APolyline, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINED, @View.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddPolyline(const APolyline: TBLArrayView; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINEI, @APolyline.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddPolyline(const APolyline: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINEI, @APolyline.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddPolyline(const APolyline: PBLPointI; const ACount: Integer; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(APolyline, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINEI, @View.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddPolyline(const APolyline: PBLPointI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(APolyline, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINEI, @View.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddRect(const AX, AY, AW, AH: Double; const ADirection: TBLGeometryDirection); var Rect: TBLRect; begin Rect.Reset(AX, AY, AW, AH); _BLCheck(blPathAddRectD(@FHandle, @Rect, Ord(ADirection))); end; procedure TBLPath.AddRect(const ARect: TBLRect; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddRectD(@FHandle, @ARect, Ord(ADirection))); end; procedure TBLPath.AddRect(const ARect: TBLRectI; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddRectI(@FHandle, @ARect, Ord(ADirection))); end; procedure TBLPath.AddRectArray(const ARects: PBLRectI; const ACount: Integer; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(ARects, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @View.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddRectArray(const ARects: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @ARects.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddRectArray(const ARects: TBLArrayView; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @ARects.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddRectArray(const ARects: PBLRectI; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(ARects, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @View.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddRectArray(const ARects: PBLRect; const ACount: Integer; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(ARects, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @View.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddRectArray(const ARects: PBLRect; const ACount: Integer; const ADirection: TBLGeometryDirection); var View: TBLArrayView; begin View.Reset(ARects, ACount); _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @View.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddRectArray(const ARects: TBLArrayView; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @ARects.FHandle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddRectArray(const ARects: TBLArrayView; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @ARects.FHandle, nil, Ord(ADirection))); end; procedure TBLPath.AddRegion(const ARegion: IBLRegion; const ADirection: TBLGeometryDirection); begin if (ARegion <> nil) then _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_REGION, ARegion.Handle, nil, Ord(ADirection))); end; procedure TBLPath.AddRegion(const ARegion: IBLRegion; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin if (ARegion <> nil) then _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_REGION, ARegion.Handle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddReversedPath(const APath: IBLPath; const AReverseMode: TBLPathReverseMode); begin if (APath <> nil) then _BLCheck(blPathAddReversedPath(@FHandle, APath.Handle, nil, Ord(AReverseMode))); end; procedure TBLPath.AddReversedPath(const APath: IBLPath; const ARange: TBLRange; const AReverseMode: TBLPathReverseMode); begin if (APath <> nil) then _BLCheck(blPathAddReversedPath(@FHandle, APath.Handle, @ARange, Ord(AReverseMode))); end; procedure TBLPath.AddRoundRect(const ARoundRect: TBLRoundRect; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @ARoundRect, nil, Ord(ADirection))); end; procedure TBLPath.AddRoundRect(const ARoundRect: TBLRoundRect; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @ARoundRect, @AMatrix, Ord(ADirection))); end; procedure TBLPath.AddStrokedPath(const APath: IBLPath; const AStrokeOptions: TBLStrokeOptions; const AApproximationOptions: TBLApproximationOptions); begin if (APath <> nil) then begin _BLCheck(blPathAddStrokedPath(@FHandle, APath.Handle, nil, @AStrokeOptions.FHandle, @AApproximationOptions.FHandle)); end; end; procedure TBLPath.AddStrokedPath(const APath: IBLPath; const ARange: TBLRange; const AStrokeOptions: TBLStrokeOptions; const AApproximationOptions: TBLApproximationOptions); begin if (APath <> nil) then begin _BLCheck(blPathAddStrokedPath(@FHandle, APath.Handle, @ARange, @AStrokeOptions.FHandle, @AApproximationOptions.FHandle)); end; end; procedure TBLPath.AddTriangle(const ATriangle: TBLTriangle; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_TRIANGLE, @ATriangle, nil, Ord(ADirection))); end; procedure TBLPath.AddTriangle(const ATriangle: TBLTriangle; const AMatrix: TBLMatrix2D; const ADirection: TBLGeometryDirection); begin _BLCheck(blPathAddGeometry(@FHandle, BL_GEOMETRY_TYPE_TRIANGLE, @ATriangle, @AMatrix, Ord(ADirection))); end; procedure TBLPath.ArcQuadrantTo(const AX1, AY1, AX2, AY2: Double); begin _BLCheck(blPathArcQuadrantTo(@FHandle, AX1, AY1, AX2, AY2)); end; procedure TBLPath.ArcQuadrantTo(const AP1, AP2: TBLPoint); begin _BLCheck(blPathArcQuadrantTo(@FHandle, AP1.FHandle.x, AP1.FHandle.y, AP2.FHandle.x, AP2.FHandle.y)); end; procedure TBLPath.ArcTo(const AC, AR: TBLPoint; const AStart, ASweep: Double; const AForceMoveTo: Boolean); begin _BLCheck(blPathArcTo(@FHandle, AC.FHandle.x, AC.FHandle.y, AR.FHandle.x, AR.FHandle.y, AStart, ASweep, AForceMoveTo)); end; procedure TBLPath.ArcTo(const ACX, ACY, ARX, ARY, AStart, ASweep: Double; const AForceMoveTo: Boolean); begin _BLCheck(blPathArcTo(@FHandle, ACX, ACY, ARX, ARY, AStart, ASweep, AForceMoveTo)); end; procedure TBLPath.Clear; begin _BLCheck(blPathClear(@FHandle)); end; function TBLPath.Clone: IBLPath; begin Result := TBLPath.Create; _BLCheck(blPathAssignDeep(Result.Handle, @FHandle)); end; procedure TBLPath.Close; begin _BLCheck(blPathClose(@FHandle)); end; constructor TBLPath.Create; begin inherited Create; blPathInit(@FHandle); end; procedure TBLPath.CubicTo(const AX1, AY1, AX2, AY2, AX3, AY3: Double); begin _BLCheck(blPathCubicTo(@FHandle, AX1, AY1, AX2, AY2, AX3, AY3)); end; procedure TBLPath.CubicTo(const AP1, AP2, AP3: TBLPoint); begin _BLCheck(blPathCubicTo(@FHandle, AP1.FHandle.x, AP1.FHandle.y, AP2.FHandle.x, AP2.FHandle.y, AP3.FHandle.x, AP3.FHandle.y)); end; destructor TBLPath.Destroy; begin blPathDestroy(@FHandle); inherited; end; procedure TBLPath.EllipticArcTo(const ARX, ARY, AXAxisRotation: Double; const ALargeArcFlag, ASweepFlag: Boolean; const AX1, AY1: Double); begin _BLCheck(blPathEllipticArcTo(@FHandle, ARX, ARY, AXAxisRotation, ALargeArcFlag, ASweepFlag, AX1, AY1)); end; procedure TBLPath.EllipticArcTo(const ARP: TBLPoint; const AXAxisRotation: Double; const ALargeArcFlag, ASweepFlag: Boolean; const AP1: TBLPoint); begin _BLCheck(blPathEllipticArcTo(@FHandle, ARP.FHandle.x, ARP.FHandle.y, AXAxisRotation, ALargeArcFlag, ASweepFlag, AP1.FHandle.x, AP1.FHandle.y)); end; function TBLPath.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLPath) then Result := blPathEquals(@FHandle, @TBLPath(Obj).FHandle) else Result := False; end; function TBLPath.Equals(const AOther: IBLPath): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := blPathEquals(@FHandle, AOther.Handle); end; procedure TBLPath.FitTo(const ARect: TBLRect; const AFitFlags: TBLFitFlags); begin _BLCheck(blPathFitTo(@FHandle, nil, @ARect, Byte(AFitFlags))); end; procedure TBLPath.FitTo(const ARange: TBLRange; const ARect: TBLRect; const AFitFlags: TBLFitFlags); begin _BLCheck(blPathFitTo(@FHandle, @ARange, @ARect, Byte(AFitFlags))); end; function TBLPath.GetBoundingBox: TBLBox; begin _BLCheck(blPathGetBoundingBox(@FHandle, @Result)); end; function TBLPath.GetCapacity: Integer; begin Result := FHandle.impl.capacity; end; function TBLPath.GetClosestVertex(const AP: TBLPoint; const AMaxDistance: Double): Integer; var Index: NativeUInt; ActualDistance: Double; begin _BLCheck(blPathGetClosestVertex(@FHandle, @AP, AMaxDistance, @Index, @ActualDistance)); Result := Index; end; function TBLPath.GetClosestVertex(const AP: TBLPoint; const AMaxDistance: Double; out AActualDistance: Double): Integer; var Index: NativeUInt; begin _BLCheck(blPathGetClosestVertex(@FHandle, @AP, AMaxDistance, @Index, @AActualDistance)); Result := Index; end; function TBLPath.GetCommandData: PBLPathCmd; begin Result := Pointer(FHandle.impl.commandData); end; function TBLPath.GetCommandDataEnd: PBLPathCmd; begin Result := Pointer(FHandle.impl.commandData + FHandle.impl.size); end; function TBLPath.GetControlBox: TBLBox; begin _BLCheck(blPathGetControlBox(@FHandle, @Result)); end; function TBLPath.GetCount: Integer; begin Result := FHandle.impl.size; end; function TBLPath.GetFigureRange(const AIndex: Integer): TBLRange; begin _BLCheck(blPathGetFigureRange(@FHandle, AIndex, @Result)); end; function TBLPath.GetHandle: PBLPathCore; begin Result := @FHandle; end; function TBLPath.GetInfoFlags: TBLPathFlags; begin _BLCheck(blPathGetInfoFlags(@FHandle, @Result)); end; function TBLPath.GetIsEmpty: Boolean; begin Result := (FHandle.impl.size = 0); end; function TBLPath.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLPath.GetLastVertex: TBLPoint; begin _BLCheck(blPathGetLastVertex(@FHandle, @Result)); end; function TBLPath.GetVertexData: PBLPoint; begin Result := Pointer(FHandle.impl.vertexData); end; function TBLPath.GetVertexDataEnd: PBLPoint; begin Result := Pointer(FHandle.impl.vertexData + FHandle.impl.size); end; function TBLPath.GetView: TBLPathView; begin Result.FHandle := FHandle.impl.view; end; function TBLPath.HitTest(const AP: TBLPoint; const AFillRule: TBLFillRule): TBLHitTest; begin Result := TBLHitTest(blPathHitTest(@FHandle, @AP, Ord(AFillRule))); end; procedure TBLPath.LineTo(const AX1, AY1: Double); begin _BLCheck(blPathLineTo(@FHandle, AX1, AY1)); end; procedure TBLPath.LineTo(const AP1: TBLPoint); begin _BLCheck(blPathLineTo(@FHandle, AP1.FHandle.x, AP1.FHandle.y)); end; procedure TBLPath.MoveTo(const AX0, AY0: Double); begin _BLCheck(blPathMoveTo(@FHandle, AX0, AY0)); end; procedure TBLPath.MoveTo(const AP0: TBLPoint); begin _BLCheck(blPathMoveTo(@FHandle, AP0.FHandle.x, AP0.FHandle.y)); end; procedure TBLPath.PolyTo(const APoly: TArray); begin _BLCheck(blPathPolyTo(@FHandle, Pointer(APoly), Length(APoly))); end; procedure TBLPath.PolyTo(const APoly: PBLPoint; const ACount: Integer); begin _BLCheck(blPathPolyTo(@FHandle, _PBLPoint(APoly), ACount)); end; procedure TBLPath.QuadTo(const AP1, AP2: TBLPoint); begin _BLCheck(blPathQuadTo(@FHandle, AP1.FHandle.x, AP1.FHandle.y, AP2.FHandle.x, AP2.FHandle.y)); end; procedure TBLPath.QuadTo(const AX1, AY1, AX2, AY2: Double); begin _BLCheck(blPathQuadTo(@FHandle, AX1, AY1, AX2, AY2)); end; procedure TBLPath.RemoveRange(const ARange: TBLRange); begin _BLCheck(blPathRemoveRange(@FHandle, @ARange.FHandle)); end; procedure TBLPath.Reserve(const ACount: Integer); begin _BLCheck(blPathReserve(@FHandle, ACount)); end; procedure TBLPath.Reset; begin _BLCheck(blPathReset(@FHandle)); end; procedure TBLPath.SetVertexAt(const AIndex: Integer; const ACmd: TBLPathCmd; const AX, AY: Double; const APreserve: Boolean); const FLAGS: array [Boolean] of Cardinal = (0, BL_PATH_CMD_PRESERVE); begin _BLCheck(blPathSetVertexAt(@FHandle, AIndex, Byte(ACmd) or FLAGS[APreserve], AX, AY)); end; procedure TBLPath.SetVertexAt(const AIndex: Integer; const ACmd: TBLPathCmd; const APt: TBLPoint; const APreserve: Boolean); const FLAGS: array [Boolean] of Cardinal = (0, BL_PATH_CMD_PRESERVE); begin _BLCheck(blPathSetVertexAt(@FHandle, AIndex, Byte(ACmd) or FLAGS[APreserve], APt.FHandle.x, APt.FHandle.y)); end; procedure TBLPath.Shrink; begin _BLCheck(blPathShrink(@FHandle)); end; procedure TBLPath.SmoothCubicTo(const AX2, AY2, AX3, AY3: Double); begin _BLCheck(blPathSmoothCubicTo(@FHandle, AX2, AY2, AX3, AY3)); end; procedure TBLPath.SmoothCubicTo(const AP2, AP3: TBLPoint); begin _BLCheck(blPathSmoothCubicTo(@FHandle, AP2.FHandle.x, AP2.FHandle.y, AP3.FHandle.x, AP3.FHandle.y)); end; procedure TBLPath.SmoothQuadTo(const AP2: TBLPoint); begin _BLCheck(blPathSmoothQuadTo(@FHandle, AP2.FHandle.x, AP2.FHandle.y)); end; procedure TBLPath.SmoothQuadTo(const AX2, AY2: Double); begin _BLCheck(blPathSmoothQuadTo(@FHandle, AX2, AY2)); end; procedure TBLPath.Transform(const ARange: TBLRange; const AMatrix: TBLMatrix2D); begin _BLCheck(blPathTransform(@FHandle, @ARange, @AMatrix)); end; procedure TBLPath.Transform(const AMatrix: TBLMatrix2D); begin _BLCheck(blPathTransform(@FHandle, nil, @AMatrix)); end; procedure TBLPath.Translate(const ARange: TBLRange; const AP: TBLPoint); begin _BLCheck(blPathTranslate(@FHandle, @ARange, @AP)); end; procedure TBLPath.Translate(const AP: TBLPoint); begin _BLCheck(blPathTranslate(@FHandle, nil, @AP)); end; {$ENDREGION 'Path'} {$REGION 'Format'} { TBLFormatInfo } class operator TBLFormatInfo.Equal(const ALeft, ARight: TBLFormatInfo): Boolean; begin Result := CompareMem(@ALeft, @ARight, SizeOf(TBLFormatInfo)); end; function TBLFormatInfo.GetFlags: TBLFormatFlags; begin Cardinal(Result) := FHandle.flags; end; function TBLFormatInfo.GetPalette: PBLRgba32; begin Result := Pointer(FHandle.palette); end; class operator TBLFormatInfo.NotEqual(const ALeft, ARight: TBLFormatInfo): Boolean; begin Result := not CompareMem(@ALeft, @ARight, SizeOf(TBLFormatInfo)); end; procedure TBLFormatInfo.Query(const AFormat: TBLFormat); begin _BLCheck(blFormatInfoQuery(@FHandle, Ord(AFormat))); end; procedure TBLFormatInfo.Reset(const ADepth: Integer; const AFlags: TBLFormatFlags; const ARSize, AGSize, ABSize, AASize, ARShift, AGShift, ABShift, AAShift: Byte); begin FHandle.depth := ADepth; FHandle.flags := Cardinal(AFlags); FHandle.rSize := ARSize; FHandle.gSize := AGSize; FHandle.bSize := ABSize; FHandle.aSize := AASize; FHandle.rShift := ARShift; FHandle.gShift := AGShift; FHandle.bShift := ABShift; FHandle.aShift := AAShift; end; procedure TBLFormatInfo.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLFormatInfo.Sanitize; begin _BLCheck(blFormatInfoSanitize(@FHandle)); end; procedure TBLFormatInfo.SetFlags(const AValue: TBLFormatFlags); begin FHandle.flags := Cardinal(AValue); end; procedure TBLFormatInfo.SetShifts(const ARShift, AGShift, ABShift, AAShift: Byte); begin FHandle.rShift := ARShift; FHandle.gShift := AGShift; FHandle.bShift := ABShift; FHandle.aShift := AAShift; end; procedure TBLFormatInfo.SetSizes(const ARSize, AGSize, ABSize, AASize: Byte); begin FHandle.rSize := ARSize; FHandle.gSize := AGSize; FHandle.bSize := ABSize; FHandle.aSize := AASize; end; { _TBLFormatHelper } function _TBLFormatHelper.GetInfo: TBLFormatInfo; begin _BLCheck(blFormatInfoQuery(@Result.FHandle, Ord(Self))); end; {$ENDREGION 'Format'} {$REGION 'Image'} { TBLImageData } function TBLImageData.GetFlags: TBLFormatFlags; begin Cardinal(Result) := FHandle.flags; end; function TBLImageData.GetFormat: TBLFormat; begin Byte(Result) := FHandle.format; end; function TBLImageData.GetSize: TBLSizeI; begin Result.FHandle := FHandle.size; end; procedure TBLImageData.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLImageData.SetFlags(const AValue: TBLFormatFlags); begin FHandle.flags := Cardinal(AValue); end; procedure TBLImageData.SetFormat(const AValue: TBLFormat); begin FHandle.format := Ord(AValue); end; procedure TBLImageData.SetSize(const AValue: TBLSizeI); begin FHandle.size := AValue.FHandle; end; { TBLImageInfo } function TBLImageInfo.GetCompression: String; begin Result := String(UTF8String(FHandle.compression)); end; function TBLImageInfo.GetDensity: TBLSize; begin Result.FHandle := FHandle.density; end; function TBLImageInfo.GetDepth: Integer; begin Result := FHandle.depth; end; function TBLImageInfo.GetFlags: TBLFormatFlags; begin Cardinal(Result) := FHandle.flags; end; function TBLImageInfo.GetFormat: String; begin Result := String(UTF8String(FHandle.format)); end; function TBLImageInfo.GetFrameCount: Integer; begin Result := FHandle.frameCount; end; function TBLImageInfo.GetPlaneCount: Integer; begin Result := FHandle.planeCount; end; function TBLImageInfo.GetSize: TBLSizeI; begin Result.FHandle := FHandle.size; end; procedure TBLImageInfo.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; { TBLImageScaleOptions } function TBLImageScaleOptions.GetUserFunc: TBLImageScaleUserFunc; begin Result := TBLImageScaleUserFunc(FHandle.userFunc); end; procedure TBLImageScaleOptions.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLImageScaleOptions.ResetToDefaults; begin FHandle.userFunc := nil; FHandle.userData := nil; FHandle.radius := 2; FHandle.mitchell.b := 1 / 3; FHandle.mitchell.c := 1 / 3; FHandle.data[2] := 0; end; procedure TBLImageScaleOptions.SetUserFunc(const AValue: TBLImageScaleUserFunc); begin TBLImageScaleUserFunc(FHandle.userFunc) := AValue; end; { TBLImage } constructor TBLImage.Create; begin inherited Create; blImageInit(@FHandle); end; function TBLImage.Clone: IBLImage; begin Result := TBLImage.Create; _BLCheck(blImageAssignDeep(Result.Handle, @FHandle)); end; procedure TBLImage.Convert(const AFormat: TBLFormat); begin _BLCheck(blImageConvert(@FHandle, Ord(AFormat))); end; constructor TBLImage.Create(const AWidth, AHeight: Integer; const AFormat: TBLFormat); begin inherited Create; _BLCheck(blImageInitAs(@FHandle, AWidth, AHeight, Ord(AFormat))); end; constructor TBLImage.Create(const AHandle: BLImageCore; const AIsReference: Boolean); begin inherited Create; FHandle := AHandle; FIsReference := AIsReference; end; destructor TBLImage.Destroy; begin if (not FIsReference) then blImageDestroy(@FHandle); inherited; end; class procedure TBLImage.DoDestroy(impl, destroyData: Pointer); var Data: PDestroyData absolute destroyData; begin if (Data <> nil) then begin Data.Event(Data.Image); FreeMem(Data); end; end; function TBLImage.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLImage) then Result := blImageEquals(@FHandle, @TBLImage(Obj).FHandle) else Result := False; end; function TBLImage.Equals(const AOther: IBLImage): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := blImageEquals(@FHandle, AOther.Handle); end; procedure TBLImage.GetData(out AData: TBLImageData); begin _BLCheck(blImageGetData(@FHandle, @AData.FHandle)); end; function TBLImage.GetFormat: TBLFormat; begin Result := TBLFormat(FHandle.impl.format); end; function TBLImage.GetHandle: PBLImageCore; begin Result := @FHandle; end; function TBLImage.GetHeight: Integer; begin Result := FHandle.impl.size.h; end; function TBLImage.GetIsEmpty: Boolean; begin Result := (FHandle.impl.format = BL_FORMAT_NONE); end; function TBLImage.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLImage.GetSize: TBLSizeI; begin Result := TBLSizeI(FHandle.impl.size); end; function TBLImage.GetWidth: Integer; begin Result := FHandle.impl.size.w; end; procedure TBLImage.Initialize(const AWidth, AHeight: Integer; const AFormat: TBLFormat); begin _BLCheck(blImageCreate(@FHandle, AWidth, AHeight, Ord(AFormat))); end; procedure TBLImage.InitializeFromData(const AWidth, AHeight: Integer; const AFormat: TBLFormat; const APixelData: Pointer; const AStride: Integer; const AOnDestroy: TBLImageDestroyEvent); var DestroyFunc: BLDestroyImplFunc; DestroyData: PDestroyData; begin if Assigned(AOnDestroy) then begin DestroyFunc := DoDestroy; GetMem(DestroyData, SizeOf(TDestroyData)); DestroyData.Image := Self; DestroyData.Event := AOnDestroy; end else begin DestroyFunc := nil; DestroyData := nil; end; _BLCheck(blImageCreateFromData(@FHandle, AWidth, AHeight, Ord(AFormat), APixelData, AStride, DestroyFunc, DestroyData)); end; procedure TBLImage.MakeMutable(out AData: TBLImageData); begin _BLCheck(blImageMakeMutable(@FHandle, @AData.FHandle)); end; procedure TBLImage.MakeMutable; var Unused: TBLImageData; begin _BLCheck(blImageMakeMutable(@FHandle, @Unused.FHandle)); end; procedure TBLImage.ReadFromData(const AData: TBytes); begin ReadFromData(Pointer(AData), Length(AData), nil); end; procedure TBLImage.ReadFromData(const AData: TBytes; const ACodecs: TArray); begin ReadFromData(Pointer(AData), Length(AData), ACodecs); end; procedure TBLImage.ReadFromData(const AData: Pointer; const ASize: Integer); begin _BLCheck(blImageReadFromData(@FHandle, AData, ASize, nil)); end; procedure TBLImage.ReadFromData(const AData: Pointer; const ASize: Integer; const ACodecs: TArray); var CodecHandles: TArray; Codecs: IBLArray; I: Integer; begin SetLength(CodecHandles, Length(ACodecs)); for I := 0 to Length(CodecHandles) - 1 do CodecHandles[I] := ACodecs[I].Handle^; Codecs := TBLUtils.ArrayToBLArray(CodecHandles); _BLCheck(blImageReadFromData(@FHandle, AData, ASize, Codecs.Handle)); end; procedure TBLImage.ReadFromData(const AView: TBLArrayView); begin ReadFromData(AView.Data, AView.Length, nil); end; procedure TBLImage.ReadFromData(const AView: TBLArrayView; const ACodecs: TArray); begin ReadFromData(AView.Data, AView.Length, ACodecs); end; procedure TBLImage.ReadFromFile(const AFilename: String); begin _BLCheck(blImageReadFromFile(@FHandle, MarshaledAString(UTF8String(AFilename)), nil)); end; procedure TBLImage.ReadFromFile(const AFilename: String; const ACodecs: TArray); var CodecHandles: TArray; Codecs: IBLArray; I: Integer; begin SetLength(CodecHandles, Length(ACodecs)); for I := 0 to Length(CodecHandles) - 1 do CodecHandles[I] := ACodecs[I].Handle^; Codecs := TBLUtils.ArrayToBLArray(CodecHandles); _BLCheck(blImageReadFromFile(@FHandle, MarshaledAString(UTF8String(AFilename)), Codecs.Handle)); end; procedure TBLImage.Reset; begin _BLCheck(blImageReset(@FHandle)); end; class procedure TBLImage.Scale(const ASrc, ADst: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter); begin if (ASrc <> nil) then ASrc.ScaleTo(ADst, ASize, AFilter); end; class procedure TBLImage.Scale(const ASrc, ADst: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter; const AOptions: TBLImageScaleOptions); begin if (ASrc <> nil) then ASrc.ScaleTo(ADst, ASize, AFilter, AOptions); end; procedure TBLImage.ScaleTo(const ADest: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter); begin if (ADest <> nil) then _BLCheck(blImageScale(ADest.Handle, @FHandle, @ASize, Ord(AFilter), nil)); end; procedure TBLImage.ScaleTo(const ADest: IBLImage; const ASize: TBLSizeI; const AFilter: TBLImageScaleFilter; const AOptions: TBLImageScaleOptions); begin if (ADest <> nil) then _BLCheck(blImageScale(ADest.Handle, @FHandle, @ASize, Ord(AFilter), @AOptions.FHandle)); end; function TBLImage.WriteToData(const ACodec: IBLImageCodec): TBytes; var Codec: PBLImageCodecCore; Data: IBLArray; begin if (ACodec = nil) then Codec := nil else Codec := ACodec.Handle; Data := TBLUtils.CreateBLArray; _BLCheck(blImageWriteToData(@FHandle, Data.Handle, Codec)); Result := TBLUtils.BLArrayToArray(Data); end; procedure TBLImage.WriteToFile(const AFilename: String); begin _BLCheck(blImageWriteToFile(@FHandle, MarshaledAString(UTF8String(AFilename)), nil)); end; procedure TBLImage.WriteToFile(const AFilename: String; const ACodec: IBLImageCodec); var Codec: PBLImageCodecCore; begin if (ACodec = nil) then Codec := nil else Codec := ACodec.Handle; _BLCheck(blImageWriteToFile(@FHandle, MarshaledAString(UTF8String(AFilename)), Codec)); end; {$ENDREGION 'Image'} {$REGION 'Image Codec'} { TBLImageDecoder } constructor TBLImageDecoder.Create; begin inherited Create; blImageDecoderInit(@FHandle); end; destructor TBLImageDecoder.Destroy; begin blImageDecoderDestroy(@FHandle); inherited; end; function TBLImageDecoder.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLImageDecoder) then Result := (FHandle.impl = @TBLImageDecoder(Obj).FHandle.impl) else Result := False; end; function TBLImageDecoder.Equals(const AOther: IBLImageDecoder): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := (FHandle.impl = AOther.Handle.impl); end; function TBLImageDecoder.GetBufferIndex: NativeInt; begin Result := FHandle.impl.bufferIndex; end; function TBLImageDecoder.GetFrameIndex: Integer; begin Result := FHandle.impl.frameIndex; end; function TBLImageDecoder.GetHandle: PBLImageDecoderCore; begin Result := @FHandle; end; function TBLImageDecoder.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLImageDecoder.GetLastResult: TBLResultCode; begin Result := TBLResultCode(FHandle.impl.lastResult); end; function TBLImageDecoder.ReadFrame(const ABuffer: Pointer; const ASize: Integer): IBLImage; begin Result := TBLImage.Create; _BLCheck(blImageDecoderReadFrame(@FHandle, Result.Handle, ABuffer, ASize)); end; function TBLImageDecoder.ReadFrame(const ABuffer: TBLArrayView): IBLImage; begin Result := TBLImage.Create; _BLCheck(blImageDecoderReadFrame(@FHandle, Result.Handle, ABuffer.FHandle.data, ABuffer.FHandle.size)); end; function TBLImageDecoder.ReadFrame(const ABuffer: TBytes): IBLImage; begin Result := TBLImage.Create; _BLCheck(blImageDecoderReadFrame(@FHandle, Result.Handle, Pointer(ABuffer), Length(ABuffer))); end; procedure TBLImageDecoder.ReadInfo(const ABuffer: Pointer; const ASize: Integer; out AInfo: TBLImageInfo); begin _BLCheck(blImageDecoderReadInfo(@FHandle, @AInfo.FHandle, ABuffer, ASize)); end; procedure TBLImageDecoder.ReadInfo(const ABuffer: TBLArrayView; out AInfo: TBLImageInfo); begin _BLCheck(blImageDecoderReadInfo(@FHandle, @AInfo.FHandle, ABuffer.FHandle.data, ABuffer.FHandle.size)); end; procedure TBLImageDecoder.ReadInfo(const ABuffer: TBytes; out AInfo: TBLImageInfo); begin _BLCheck(blImageDecoderReadInfo(@FHandle, @AInfo.FHandle, Pointer(ABuffer), Length(ABuffer))); end; procedure TBLImageDecoder.Reset; begin _BLCheck(blImageDecoderReset(@FHandle)); end; procedure TBLImageDecoder.Restart; begin _BLCheck(blImageDecoderRestart(@FHandle)); end; { TBLImageEncoder } constructor TBLImageEncoder.Create; begin inherited Create; blImageEncoderInit(@FHandle); end; destructor TBLImageEncoder.Destroy; begin blImageEncoderDestroy(@FHandle); inherited; end; function TBLImageEncoder.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLImageEncoder) then Result := (FHandle.impl = @TBLImageEncoder(Obj).FHandle.impl) else Result := False; end; function TBLImageEncoder.Equals(const AOther: IBLImageEncoder): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := (FHandle.impl = AOther.Handle.impl); end; function TBLImageEncoder.GetBufferIndex: NativeInt; begin Result := FHandle.impl.bufferIndex; end; function TBLImageEncoder.GetFrameIndex: Integer; begin Result := FHandle.impl.frameIndex; end; function TBLImageEncoder.GetHandle: PBLImageEncoderCore; begin Result := @FHandle; end; function TBLImageEncoder.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLImageEncoder.GetLastResult: TBLResultCode; begin Result := TBLResultCode(FHandle.impl.lastResult); end; procedure TBLImageEncoder.Reset; begin _BLCheck(blImageEncoderReset(@FHandle)); end; procedure TBLImageEncoder.Restart; begin _BLCheck(blImageEncoderRestart(@FHandle)); end; function TBLImageEncoder.WriteFrame(const AImage: IBLImage): TBytes; var Dest: IBLArray; begin if (AImage <> nil) then begin Dest := TBLUtils.CreateBLArray; _BLCheck(blImageEncoderWriteFrame(@FHandle, Dest.Handle, AImage.Handle)); Result := TBLUtils.BLArrayToArray(Dest); end; end; { TBLImageCodec } class procedure TBLImageCodec.AddToBuiltIn(const ACodec: IBLImageCodec); begin if (ACodec <> nil) then _BLCheck(blImageCodecAddToBuiltIn(ACodec.Handle)); end; constructor TBLImageCodec.Create; begin inherited Create; blImageCodecInit(@FHandle); end; constructor TBLImageCodec.Create(const AHandle: BLImageCodecCore; const AIsReference: Boolean); begin inherited Create; FHandle := AHandle; FIsReference := AIsReference; end; destructor TBLImageCodec.Destroy; begin if (not FIsReference) then blImageCodecDestroy(@FHandle); inherited; end; function TBLImageCodec.Equals(const AOther: IBLImageCodec): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := (FHandle.impl = AOther.Handle.impl); end; function TBLImageCodec.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLImageCodec) then Result := (FHandle.impl = @TBLImageCodec(Obj).FHandle.impl) else Result := False; end; function TBLImageCodec.FindByData(const AData: TBytes; const ACodecs: TArray): Boolean; begin Result := FindByData(Pointer(AData), Length(AData), ACodecs); end; function TBLImageCodec.FindByExtension(const AExt: String; const ACodecs: TArray): Boolean; var CodecHandles: TArray; CodecArray: IBLArray; Codecs: PBLArrayCore; Ext: UTF8String; Res: BLResultCode; I: Integer; begin if Assigned(ACodecs) then begin SetLength(CodecHandles, Length(ACodecs)); for I := 0 to Length(CodecHandles) - 1 do CodecHandles[I] := ACodecs[I].Handle^; CodecArray := TBLUtils.ArrayToBLArray(CodecHandles); Codecs := CodecArray.Handle; end else Codecs := nil; Ext := UTF8String(AExt); Res := blImageCodecFindByExtension(@FHandle, MarshaledAString(Ext), Length(Ext), Codecs); Result := (Res = BL_SUCCESS); if (Res <> BL_ERROR_IMAGE_NO_MATCHING_CODEC) then _BLCheck(Res); end; function TBLImageCodec.FindByExtension(const AExt: String): Boolean; var Ext: UTF8String; Res: BLResultCode; begin Ext := UTF8String(AExt); Res := blImageCodecFindByExtension(@FHandle, MarshaledAString(Ext), Length(Ext), nil); Result := (Res = BL_SUCCESS); if (Res <> BL_ERROR_IMAGE_NO_MATCHING_CODEC) then _BLCheck(Res); end; function TBLImageCodec.FindByData(const AData: Pointer; const ASize: Integer): Boolean; var Res: BLResultCode; begin Res := blImageCodecFindByData(@FHandle, AData, ASize, nil); Result := (Res = BL_SUCCESS); if (Res <> BL_ERROR_IMAGE_NO_MATCHING_CODEC) then _BLCheck(Res); end; function TBLImageCodec.FindByData(const AData: Pointer; const ASize: Integer; const ACodecs: TArray): Boolean; var CodecHandles: TArray; CodecArray: IBLArray; Codecs: PBLArrayCore; Res: BLResultCode; I: Integer; begin if Assigned(ACodecs) then begin SetLength(CodecHandles, Length(ACodecs)); for I := 0 to Length(CodecHandles) - 1 do CodecHandles[I] := ACodecs[I].Handle^; CodecArray := TBLUtils.ArrayToBLArray(CodecHandles); Codecs := CodecArray.Handle; end else Codecs := nil; Res := blImageCodecFindByData(@FHandle, AData, ASize, Codecs); Result := (Res = BL_SUCCESS); if (Res <> BL_ERROR_IMAGE_NO_MATCHING_CODEC) then _BLCheck(Res); end; function TBLImageCodec.FindByData(const AData: TBytes): Boolean; var Res: BLResultCode; begin Res := blImageCodecFindByData(@FHandle, Pointer(AData), Length(AData), nil); Result := (Res = BL_SUCCESS); if (Res <> BL_ERROR_IMAGE_NO_MATCHING_CODEC) then _BLCheck(Res); end; function TBLImageCodec.FindByName(const AName: String; const ACodecs: TArray): Boolean; var CodecHandles: TArray; CodecArray: IBLArray; Codecs: PBLArrayCore; Name: UTF8String; Res: BLResultCode; I: Integer; begin if Assigned(ACodecs) then begin SetLength(CodecHandles, Length(ACodecs)); for I := 0 to Length(CodecHandles) - 1 do CodecHandles[I] := ACodecs[I].Handle^; CodecArray := TBLUtils.ArrayToBLArray(CodecHandles); Codecs := CodecArray.Handle; end else Codecs := nil; Name := UTF8String(AName); Res := blImageCodecFindByName(@FHandle, MarshaledAString(Name), Length(Name), Codecs); Result := (Res = BL_SUCCESS); if (Res <> BL_ERROR_IMAGE_NO_MATCHING_CODEC) then _BLCheck(Res); end; function TBLImageCodec.FindByName(const AName: String): Boolean; var Name: UTF8String; Res: BLResultCode; begin Name := UTF8String(AName); Res := blImageCodecFindByName(@FHandle, MarshaledAString(Name), Length(Name), nil); Result := (Res = BL_SUCCESS); if (Res <> BL_ERROR_IMAGE_NO_MATCHING_CODEC) then _BLCheck(Res); end; class function TBLImageCodec.GetBuiltInCodecs: TArray; var CodecArray: IBLArray; CodecHandles: TArray; I: Integer; begin CodecArray := TBLUtils.CreateBLArray; _BLCheck(blImageCodecArrayInitBuiltInCodecs(CodecArray.Handle)); CodecHandles := TBLUtils.BLArrayToArray(CodecArray); SetLength(Result, Length(CodecHandles)); for I := 0 to Length(Result) - 1 do Result[I] := TBLImageCodec.Create(CodecHandles[I], True); end; function TBLImageCodec.GetExtensions: String; begin Result := String(UTF8String(FHandle.impl.extensions)); end; function TBLImageCodec.GetFeatures: TBLImageCodecFeatures; begin Result := TBLImageCodecFeatures(FHandle.impl.features); end; function TBLImageCodec.GetHandle: PBLImageCodecCore; begin Result := @FHandle; end; function TBLImageCodec.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLImageCodec.GetMimeType: String; begin Result := String(UTF8String(FHandle.impl.mimeType)); end; function TBLImageCodec.GetName: String; begin Result := String(UTF8String(FHandle.impl.name)); end; function TBLImageCodec.GetVendor: String; begin Result := String(UTF8String(FHandle.impl.vendor)); end; function TBLImageCodec.HasFeature( const AFeature: TBLImageCodecFeature): Boolean; begin Result := ((FHandle.impl.features and Ord(AFeature)) <> 0); end; function TBLImageCodec.InspectData(const ABuffer: TBytes): Cardinal; begin Result := blImageCodecInspectData(@FHandle, Pointer(ABuffer), Length(ABuffer)); end; function TBLImageCodec.InspectData(const ABuffer: TBLArrayView): Cardinal; begin Result := blImageCodecInspectData(@FHandle, ABuffer.FHandle.data, ABuffer.FHandle.size); end; function TBLImageCodec.InspectData(const ABuffer: Pointer; const ASize: Integer): Cardinal; begin Result := blImageCodecInspectData(@FHandle, ABuffer, ASize); end; class procedure TBLImageCodec.RemoveFromBuiltIn(const ACodec: IBLImageCodec); begin if (ACodec <> nil) then _BLCheck(blImageCodecRemoveFromBuiltIn(ACodec.Handle)); end; procedure TBLImageCodec.Reset; begin _BLCheck(blImageCodecReset(@FHandle)); end; {$ENDREGION 'Image Codec'} {$REGION 'Pattern'} { TBLPattern } constructor TBLPattern.Create; begin inherited; blPatternInit(@FHandle); end; constructor TBLPattern.Create(const AImage: IBLImage; const AExtendMode: TBLExtendMode); begin inherited Create; FImage := AImage; if (AImage = nil) then blPatternInit(@FHandle) else _BLCheck(blPatternInitAs(@FHandle, AImage.Handle, nil, Ord(AExtendMode), nil)); end; constructor TBLPattern.Create(const AImage: IBLImage; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); begin inherited Create; FImage := AImage; if (AImage = nil) then blPatternInit(@FHandle) else _BLCheck(blPatternInitAs(@FHandle, AImage.Handle, nil, Ord(AExtendMode), @AMatrix)); end; constructor TBLPattern.Create(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode); begin inherited Create; FImage := AImage; if (AImage = nil) then blPatternInit(@FHandle) else _BLCheck(blPatternInitAs(@FHandle, AImage.Handle, @AArea, Ord(AExtendMode), nil)); end; constructor TBLPattern.Create(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); begin inherited Create; FImage := AImage; if (AImage = nil) then blPatternInit(@FHandle) else _BLCheck(blPatternInitAs(@FHandle, AImage.Handle, @AArea, Ord(AExtendMode), @AMatrix)); end; constructor TBLPattern.Create(const AHandle: BLPatternCore; const AIsReference: Boolean); begin inherited Create; FHandle := AHandle; FIsReference := AIsReference; FImage := TBLImage.Create(FHandle.impl.image, True); end; destructor TBLPattern.Destroy; begin if (not FIsReference) then blPatternDestroy(@FHandle); inherited; end; function TBLPattern.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLPattern) then Result := blPatternEquals(@FHandle, @TBLPattern(Obj).FHandle) else Result := False; end; function TBLPattern.Equals(const AOther: IBLPattern): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := blPatternEquals(@FHandle, AOther.Handle) end; function TBLPattern.GetArea: TBLRectI; begin Result.FHandle := FHandle.impl.area; end; function TBLPattern.GetExtendMode: TBLExtendMode; begin Result := TBLExtendMode(FHandle.impl.extendMode); end; function TBLPattern.GetHandle: PBLPatternCore; begin Result := @FHandle; end; function TBLPattern.GetHasMatrix: Boolean; begin Result := (FHandle.impl.matrixType <> BL_MATRIX2D_TYPE_IDENTITY); end; function TBLPattern.GetImage: IBLImage; begin Result := FImage; end; function TBLPattern.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLPattern.GetMatrix: TBLMatrix2D; begin Result.FHandle := FHandle.impl.matrix; end; function TBLPattern.GetMatrixType: TBLMatrix2DType; begin Result := TBLMatrix2DType(FHandle.impl.matrixType); end; procedure TBLPattern.Initialize(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); begin FImage := AImage; if (AImage <> nil) then _BLCheck(blPatternCreate(@FHandle, AImage.Handle, @AArea, Ord(AExtendMode), @AMatrix)); end; procedure TBLPattern.Initialize(const AImage: IBLImage; const AExtendMode: TBLExtendMode); begin FImage := AImage; if (AImage <> nil) then _BLCheck(blPatternCreate(@FHandle, AImage.Handle, nil, Ord(AExtendMode), nil)); end; procedure TBLPattern.Initialize(const AImage: IBLImage; const AExtendMode: TBLExtendMode; const AMatrix: TBLMatrix2D); begin FImage := AImage; if (AImage <> nil) then _BLCheck(blPatternCreate(@FHandle, AImage.Handle, nil, Ord(AExtendMode), @AMatrix)); end; procedure TBLPattern.Initialize(const AImage: IBLImage; const AArea: TBLRectI; const AExtendMode: TBLExtendMode); begin FImage := AImage; if (AImage <> nil) then _BLCheck(blPatternCreate(@FHandle, AImage.Handle, @AArea, Ord(AExtendMode), nil)); end; procedure TBLPattern.PostRotate(const AAngle: Double); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE, @AAngle)); end; procedure TBLPattern.PostRotate(const AAngle, AX, AY: Double); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AX; Data[2] := AY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLPattern.PostRotate(const AAngle: Double; const AP: TBLPointI); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLPattern.PostRotate(const AAngle: Double; const AP: TBLPoint); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLPattern.PostScale(const AP: TBLPoint); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @AP)); end; procedure TBLPattern.PostScale(const AP: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := AP.FHandle.x; Data[1] := AP.FHandle.y; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @Data)); end; procedure TBLPattern.PostScale(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @Data)); end; procedure TBLPattern.PostScale(const AXY: Double); var Data: array [0..1] of Double; begin Data[0] := AXY; Data[1] := AXY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @Data)); end; procedure TBLPattern.PostSkew(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SKEW, @Data)); end; procedure TBLPattern.PostSkew(const AP: TBLPoint); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SKEW, @AP)); end; procedure TBLPattern.PostTransform(const AMatrix: TBLMatrix2D); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSFORM, @AMatrix)); end; procedure TBLPattern.PostTranslate(const AP: TBLPoint); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSLATE, @AP)); end; procedure TBLPattern.PostTranslate(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSLATE, @Data)); end; procedure TBLPattern.PostTranslate(const AP: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := AP.FHandle.x; Data[1] := AP.FHandle.y; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSLATE, @Data)); end; procedure TBLPattern.Reset; begin _BLCheck(blPatternReset(@FHandle)); end; procedure TBLPattern.ResetArea; var Area: TBLRectI; begin Area.Reset(0, 0, 0, 0); _BLCheck(blPatternSetArea(@FHandle, @Area)); end; procedure TBLPattern.ResetExtendMode; begin _BLCheck(blPatternSetExtendMode(@FHandle, BL_EXTEND_MODE_REPEAT)); end; procedure TBLPattern.ResetImage; begin FImage := TBLImage.Create; _BLCheck(blPatternSetImage(@FHandle, FImage.Handle, nil)); end; procedure TBLPattern.ResetMatrix; begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_RESET, nil)); end; procedure TBLPattern.Rotate(const AAngle: Double; const AP: TBLPoint); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLPattern.Rotate(const AAngle, AX, AY: Double); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AX; Data[2] := AY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLPattern.Rotate(const AAngle: Double); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE, @AAngle)); end; procedure TBLPattern.Rotate(const AAngle: Double; const AP: TBLPointI); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AP.FHandle.x; Data[2] := AP.FHandle.y; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLPattern.Scale(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @Data)); end; procedure TBLPattern.Scale(const AXY: Double); var Data: array [0..1] of Double; begin Data[0] := AXY; Data[1] := AXY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @Data)); end; procedure TBLPattern.Scale(const AP: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := AP.FHandle.x; Data[1] := AP.FHandle.y; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @Data)); end; procedure TBLPattern.Scale(const AP: TBLPoint); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @AP)); end; procedure TBLPattern.SetArea(const AValue: TBLRectI); begin _BLCheck(blPatternSetArea(@FHandle, @AValue)); end; procedure TBLPattern.SetExtendMode(const AValue: TBLExtendMode); begin _BLCheck(blPatternSetExtendMode(@FHandle, Ord(AValue))); end; procedure TBLPattern.SetImage(const AValue: IBLImage; const AArea: TBLRectI); begin if (AValue <> nil) then _BLCheck(blPatternSetImage(@FHandle, AValue.Handle, @AArea)); end; procedure TBLPattern.SetImage(const AValue: IBLImage); begin if (AValue <> nil) then _BLCheck(blPatternSetImage(@FHandle, AValue.Handle, nil)); end; procedure TBLPattern.SetMatrix(const AValue: TBLMatrix2D); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_ASSIGN, @AValue)); end; procedure TBLPattern.Skew(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SKEW, @Data)); end; procedure TBLPattern.Skew(const AP: TBLPoint); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_SKEW, @AP)); end; procedure TBLPattern.Transform(const AMatrix: TBLMatrix2D); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSFORM, @AMatrix)); end; procedure TBLPattern.Translate(const AP: TBLPoint); begin _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSLATE, @AP)); end; procedure TBLPattern.Translate(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSLATE, @Data)); end; procedure TBLPattern.Translate(const AP: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := AP.FHandle.x; Data[1] := AP.FHandle.y; _BLCheck(blPatternApplyMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSLATE, @Data)); end; {$ENDREGION 'Pattern'} {$REGION 'Font Defs'} { TBLGlyphInfo } procedure TBLGlyphInfo.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; { TBLGlyphPlacement } function TBLGlyphPlacement.GetAdvance: TBLPointI; begin Result.FHandle := FHandle.advance; end; function TBLGlyphPlacement.GetPlacement: TBLPointI; begin Result.FHandle := FHandle.placement; end; procedure TBLGlyphPlacement.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLGlyphPlacement.SetAdvance(const AValue: TBLPointI); begin FHandle.advance := AValue.FHandle; end; procedure TBLGlyphPlacement.SetPlacement(const AValue: TBLPointI); begin FHandle.placement := AValue.FHandle; end; { TBLGlyphMappingState } function TBLGlyphMappingState.GetGlyphCount: Integer; begin Result := FHandle.glyphCount; end; function TBLGlyphMappingState.GetUndefinedCount: Integer; begin Result := FHandle.undefinedCount; end; function TBLGlyphMappingState.GetUndefinedFirst: Integer; begin Result := FHandle.undefinedFirst; end; procedure TBLGlyphMappingState.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLGlyphMappingState.SetGlyphCount(const AValue: Integer); begin FHandle.glyphCount := AValue; end; procedure TBLGlyphMappingState.SetUndefinedCount(const AValue: Integer); begin FHandle.undefinedCount := AValue; end; procedure TBLGlyphMappingState.SetUndefinedFirst(const AValue: Integer); begin FHandle.undefinedFirst := AValue; end; { TBLGlyphOutlineSinkInfo } function TBLGlyphOutlineSinkInfo.GetContourCount: Integer; begin Result := FHandle.contourCount; end; function TBLGlyphOutlineSinkInfo.GetGlyphIndex: Integer; begin Result := FHandle.glyphIndex; end; procedure TBLGlyphOutlineSinkInfo.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLGlyphOutlineSinkInfo.SetContourCount(const AValue: Integer); begin FHandle.contourCount := AValue; end; procedure TBLGlyphOutlineSinkInfo.SetGlyphIndex(const AValue: Integer); begin FHandle.glyphIndex := AValue; end; { TBLGlyphRun } function TBLGlyphRun.Entries: TEnumerable; begin Result := TEnumerable.Create(@FHandle); end; function TBLGlyphRun.GetFlags: TBLGlyphRunFlags; begin Cardinal(Result) := FHandle.flags; end; function TBLGlyphRun.GetIsEmpty: Boolean; begin Result := (FHandle.size = 0); end; function TBLGlyphRun.GetPlacementType: TBLGlyphPlacementType; begin Result := TBLGlyphPlacementType(FHandle.placementType); end; function TBLGlyphRun.GetSize: Integer; begin Result := FHandle.size; end; procedure TBLGlyphRun.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLGlyphRun.ResetGlyphIdData; begin FHandle.glyphData := nil; FHandle.glyphAdvance := 0; end; procedure TBLGlyphRun.ResetPlacementData; begin FHandle.placementData := nil; FHandle.placementAdvance := 0; end; procedure TBLGlyphRun.SetFlags(const AValue: TBLGlyphRunFlags); begin FHandle.flags := Cardinal(AValue); end; procedure TBLGlyphRun.SetGlyphData(const AData: Pointer; const AAdvance: Integer); begin FHandle.glyphData := AData; FHandle.glyphAdvance := AAdvance; end; procedure TBLGlyphRun.SetGlyphData(const AData: PCardinal); begin FHandle.glyphData := AData; FHandle.glyphAdvance := SizeOf(Cardinal); end; procedure TBLGlyphRun.SetGlyphData(const AData: PWord); begin FHandle.glyphData := AData; FHandle.glyphAdvance := SizeOf(Word); end; procedure TBLGlyphRun.SetPlacementData(const AData: Pointer; const AAdvance: Integer); begin FHandle.placementData := AData; FHandle.placementAdvance := AAdvance; end; procedure TBLGlyphRun.SetPlacementType(const AValue: TBLGlyphPlacementType); begin FHandle.placementType := Ord(AValue); end; procedure TBLGlyphRun.SetSize(const AValue: Integer); begin FHandle.size := AValue; end; { TBLGlyphRun.TEnumerable } constructor TBLGlyphRun.TEnumerable.Create(const AHandle: _PBLGlyphRun); begin FHandle := AHandle; end; function TBLGlyphRun.TEnumerable.GetEnumerator: TEnumerator; begin Result := TEnumerator.Create(FHandle); end; { TBLGlyphRun.TEnumerator } constructor TBLGlyphRun.TEnumerator.Create(const AHandle: _PBLGlyphRun); begin FGlyphData := AHandle.glyphData; FPlacementData := AHandle.placementData; FGlyphAdvance := AHandle.glyphAdvance; FPlacementAdvance := AHandle.placementAdvance; FHigh := AHandle.size; Dec(FHigh); FIndex := -1; Dec(FGlyphData, FGlyphAdvance); Dec(FPlacementData, FPlacementAdvance); end; function TBLGlyphRun.TEnumerator.GetCurrent: TBLGlyphRunEntry; begin Result.GlyphId := PWord(FGlyphData)^; Result.Placement := P(FPlacementData)^; end; function TBLGlyphRun.TEnumerator.MoveNext: Boolean; begin Result := (FIndex < FHigh); if Result then begin Inc(FIndex); Inc(FGlyphData, FGlyphAdvance); Inc(FPlacementData, FPlacementAdvance); end; end; { TBLFontFaceInfo } function TBLFontFaceInfo.GetDiagFlags: TBLFontFaceDiagFlags; begin Word(Result) := FHandle.diagFlags; end; function TBLFontFaceInfo.GetFaceFlags: TBLFontFaceFlags; begin Cardinal(Result) := FHandle.faceFlags; end; function TBLFontFaceInfo.GetFaceType: TBLFontFaceType; begin Result := TBLFontFaceType(FHandle.faceType); end; function TBLFontFaceInfo.GetGlyphCount: Integer; begin Result := FHandle.glyphCount; end; function TBLFontFaceInfo.GetOutlineType: TBLFontOutlineType; begin Result := TBLFontOutlineType(FHandle.outlineType); end; procedure TBLFontFaceInfo.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLFontFaceInfo.SetDiagFlags(const AValue: TBLFontFaceDiagFlags); begin FHandle.diagFlags := Word(AValue); end; procedure TBLFontFaceInfo.SetFaceFlags(const AValue: TBLFontFaceFlags); begin FHandle.faceFlags := Cardinal(AValue); end; procedure TBLFontFaceInfo.SetFaceType(const AValue: TBLFontFaceType); begin FHandle.faceType := Ord(AValue); end; procedure TBLFontFaceInfo.SetGlyphCount(const AValue: Integer); begin FHandle.glyphCount := AValue; end; procedure TBLFontFaceInfo.SetOutlineType(const AValue: TBLFontOutlineType); begin FHandle.outlineType := Ord(AValue); end; { TBLFontQueryProperties } function TBLFontQueryProperties.GetStretch: TBLFontStretch; begin Result := TBLFontStretch(FHandle.stretch); end; function TBLFontQueryProperties.GetStyle: TBLFontStyle; begin Result := TBLFontStyle(FHandle.style); end; function TBLFontQueryProperties.GetWeight: TBLFontWeight; begin Result := TBLFontWeight(FHandle.weight); end; procedure TBLFontQueryProperties.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLFontQueryProperties.SetStretch(const AValue: TBLFontStretch); begin FHandle.stretch := Ord(AValue); end; procedure TBLFontQueryProperties.SetStyle(const AValue: TBLFontStyle); begin FHandle.style := Ord(AValue); end; procedure TBLFontQueryProperties.SetWeight(const AValue: TBLFontWeight); begin FHandle.weight := Ord(AValue); end; { TBLFontTable } function TBLFontTable.GetSize: Integer; begin Result := FHandle.size; end; procedure TBLFontTable.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLFontTable.Reset(const AData: Pointer; const ASize: Integer); begin FHandle.data := AData; FHandle.size := ASize; end; procedure TBLFontTable.SetSize(const AValue: Integer); begin FHandle.size := AValue; end; { TBLFontFeature } procedure TBLFontFeature.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; { TBLFontVariation } procedure TBLFontVariation.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; { TBLFontUnicodeCoverage } procedure TBLFontUnicodeCoverage.ClearBit( const AIndex: TBLFontUnicodeCoverageIndex); var I: Integer; begin I := Ord(AIndex); FHandle.data[I shr 5] := FHandle.data[I shr 5] and not (1 shl (I and 31)); end; class operator TBLFontUnicodeCoverage.Equal(const ALeft, ARight: TBLFontUnicodeCoverage): Boolean; begin Result := (ALeft.FHandle.data[0] = ARight.FHandle.data[0]) and (ALeft.FHandle.data[1] = ARight.FHandle.data[1]) and (ALeft.FHandle.data[2] = ARight.FHandle.data[2]) and (ALeft.FHandle.data[3] = ARight.FHandle.data[3]); end; function TBLFontUnicodeCoverage.GetBit( const AIndex: TBLFontUnicodeCoverageIndex): Boolean; var I: Integer; begin I := Ord(AIndex); Result := (((FHandle.data[I shr 5] shr (I and 31)) and 1) <> 0); end; function TBLFontUnicodeCoverage.GetIsEmpty: Boolean; begin Result := (FHandle.data[0] = 0) and (FHandle.data[1] = 0) and (FHandle.data[2] = 0) and (FHandle.data[3] = 0); end; class operator TBLFontUnicodeCoverage.NotEqual(const ALeft, ARight: TBLFontUnicodeCoverage): Boolean; begin Result := not (ALeft = ARight); end; procedure TBLFontUnicodeCoverage.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLFontUnicodeCoverage.SetBit( const AIndex: TBLFontUnicodeCoverageIndex; const AValue: Boolean); begin if (AValue) then SetBit(AIndex) else ClearBit(AIndex); end; procedure TBLFontUnicodeCoverage.SetBit( const AIndex: TBLFontUnicodeCoverageIndex); var I: Integer; begin I := Ord(AIndex); FHandle.data[I shr 5] := FHandle.data[I shr 5] or (1 shl (I and 31)); end; { TBLFontPanose } function TBLFontPanose.GetIsEmpty: Boolean; begin Result := (Data[0] = 0) and (Data[1] = 0) and (Data[2] = 0) and (Data[3] = 0) and (Data[4] = 0) and (Data[5] = 0) and (Data[6] = 0) and (Data[7] = 0) and (Data[8] = 0) and (Data[9] = 0); end; procedure TBLFontPanose.Reset; begin FillChar(Self, SizeOf(Self), 0); end; { TBLFontMatrix } function BLFontMatrix(const AM00, AM01, AM10, AM11: Double): TBLFontMatrix; inline; begin Result.Reset(AM00, AM01, AM10, AM11); end; function TBLFontMatrix.GetElement(const AIndex: Integer): Double; begin Assert(Cardinal(AIndex) < 4); Result := FHandle.m[AIndex]; end; procedure TBLFontMatrix.Reset; begin FHandle.m00 := 1; FHandle.m01 := 0; FHandle.m10 := 0; FHandle.m11 := 1; end; procedure TBLFontMatrix.Reset(const AM00, AM01, AM10, AM11: Double); begin FHandle.m00 := AM00; FHandle.m01 := AM01; FHandle.m10 := AM10; FHandle.m11 := AM11; end; procedure TBLFontMatrix.SetElement(const AIndex: Integer; const AValue: Double); begin Assert(Cardinal(AIndex) < 4); FHandle.m[AIndex] := AValue; end; { TBLFontMetrics } procedure TBLFontMetrics.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; { TBLFontDesignMetrics } function TBLFontDesignMetrics.GetGlyphBoundingBox: TBLBoxI; begin Result.FHandle := FHandle.glyphBoundingBox; end; procedure TBLFontDesignMetrics.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLFontDesignMetrics.SetGlyphBoundingBox(const AValue: TBLBoxI); begin FHandle.glyphBoundingBox := AValue.FHandle; end; { TBLTextMetrics } function TBLTextMetrics.GetAdvance: TBLPoint; begin Result.FHandle := FHandle.advance; end; function TBLTextMetrics.GetBoundingBox: TBLBox; begin Result.FHandle := FHandle.boundingBox; end; function TBLTextMetrics.GetLeadingBearing: TBLPoint; begin Result.FHandle := FHandle.leadingBearing; end; function TBLTextMetrics.GetTrailingBearing: TBLPoint; begin Result.FHandle := FHandle.trailingBearing; end; procedure TBLTextMetrics.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLTextMetrics.SetAdvance(const AValue: TBLPoint); begin FHandle.advance := AValue.FHandle; end; procedure TBLTextMetrics.SetBoundingBox(const AValue: TBLBox); begin FHandle.boundingBox := AValue.FHandle; end; procedure TBLTextMetrics.SetLeadingBearing(const AValue: TBLPoint); begin FHandle.leadingBearing := AValue.FHandle; end; procedure TBLTextMetrics.SetTrailingBearing(const AValue: TBLPoint); begin FHandle.trailingBearing := AValue.FHandle; end; {$ENDREGION 'Font Defs'} {$REGION 'Glyph Buffer'} { TBLGlyphBuffer } procedure TBLGlyphBuffer.Clear; begin _BLCheck(blGlyphBufferClear(@FHandle)); end; constructor TBLGlyphBuffer.Create; begin inherited; blGlyphBufferInit(@FHandle); end; destructor TBLGlyphBuffer.Destroy; begin blGlyphBufferDestroy(@FHandle); inherited; end; function TBLGlyphBuffer.GetContent: PCardinal; begin Result := PCardinal(FHandle.impl.data.content); end; function TBLGlyphBuffer.GetFlags: TBLGlyphRunFlags; begin Cardinal(Result) := FHandle.impl.data.flags; end; function TBLGlyphBuffer.GetGlyphRun: PBLGlyphRun; begin Result := @FHandle.impl.data.glyphRun; end; function TBLGlyphBuffer.GetHandle: PBLGlyphBufferCore; begin Result := @FHandle; end; function TBLGlyphBuffer.GetHasGlyphs: Boolean; begin Result := ((FHandle.impl.data.flags and BL_GLYPH_RUN_FLAG_UCS4_CONTENT) = 0); end; function TBLGlyphBuffer.GetHasInvalidChars: Boolean; begin Result := ((FHandle.impl.data.flags and BL_GLYPH_RUN_FLAG_INVALID_TEXT) <> 0); end; function TBLGlyphBuffer.GetHasInvalidFontData: Boolean; begin Result := ((FHandle.impl.data.flags and BL_GLYPH_RUN_FLAG_INVALID_FONT_DATA) <> 0); end; function TBLGlyphBuffer.GetHasText: Boolean; begin Result := ((FHandle.impl.data.flags and BL_GLYPH_RUN_FLAG_UCS4_CONTENT) <> 0); end; function TBLGlyphBuffer.GetHasUndefinedChars: Boolean; begin Result := ((FHandle.impl.data.flags and BL_GLYPH_RUN_FLAG_UNDEFINED_GLYPHS) <> 0); end; function TBLGlyphBuffer.GetInfoData: PBLGlyphInfo; begin Result := PBLGlyphInfo(FHandle.impl.infoData); end; function TBLGlyphBuffer.GetIsEmpty: Boolean; begin Result := (FHandle.impl.data.glyphRun.size = 0); end; function TBLGlyphBuffer.GetPlacementData: PBLGlyphPlacement; begin Result := PBLGlyphPlacement(FHandle.impl.data.placementData); end; function TBLGlyphBuffer.GetSize: Integer; begin Result := FHandle.impl.data.size; end; function TBLGlyphBuffer.HasFlag(const AFlag: TBLGlyphRunFlag): Boolean; begin Result := ((FHandle.impl.data.flags and Ord(AFlag)) <> 0); end; procedure TBLGlyphBuffer.Reset; begin _BLCheck(blGlyphBufferReset(@FHandle)); end; procedure TBLGlyphBuffer.SetGlyphs(const AGlyphData: Pointer; const ASize, AGlyphIdSize, AGlyphAdvance: Integer); begin _BLCheck(blGlyphBufferSetGlyphsFromStruct(@FHandle, AGlyphData, ASize, AGlyphIdSize, AGlyphAdvance)); end; procedure TBLGlyphBuffer.SetGlyphs(const AGlyphData: PCardinal; const ALength: Integer); begin _BLCheck(blGlyphBufferSetGlyphs(@FHandle, Pointer(AGlyphData), ALength)); end; procedure TBLGlyphBuffer.SetGlyphs(const AGlyphData: TArray); begin _BLCheck(blGlyphBufferSetGlyphs(@FHandle, Pointer(AGlyphData), Length(AGlyphData))); end; procedure TBLGlyphBuffer.SetText(const AText: String); begin _BLCheck(blGlyphBufferSetText(@FHandle, PChar(AText), Length(AText), BL_TEXT_ENCODING_UTF16)); end; procedure TBLGlyphBuffer.SetText(const AText: Pointer; const ALength: Integer; const AEncoding: TBLTextEncoding); begin _BLCheck(blGlyphBufferSetText(@FHandle, AText, ALength, Ord(AEncoding))); end; procedure TBLGlyphBuffer.SetText(const AText: UCS4String); begin _BLCheck(blGlyphBufferSetText(@FHandle, Pointer(AText), Length(AText) - 1, BL_TEXT_ENCODING_UTF32)); end; procedure TBLGlyphBuffer.SetText(const AText: UTF8String); begin _BLCheck(blGlyphBufferSetText(@FHandle, PUTF8Char(AText), Length(AText), BL_TEXT_ENCODING_UTF8)); end; {$ENDREGION 'Glyph Buffer'} {$REGION 'Font'} { TBLFontData } constructor TBLFontData.Create; begin inherited; blFontDataInit(@FHandle); end; constructor TBLFontData.Create(const AHandle: BLFontDataCore; const AIsReference: Boolean); begin inherited Create; FHandle := AHandle; FIsReference := AIsReference; end; destructor TBLFontData.Destroy; begin if (not FIsReference) then blFontDataDestroy(@FHandle); inherited; end; class procedure TBLFontData.DoDestroy(impl, destroyData: Pointer); var Data: PDestroyData absolute destroyData; begin if (Data <> nil) then begin Data.Event(Data.FontData); FreeMem(Data); end; end; function TBLFontData.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLFontData) then Result := blFontDataEquals(@FHandle, @TBLFontData(Obj).FHandle) else Result := False; end; function TBLFontData.Equals(const AOther: IBLFontData): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := blFontDataEquals(@FHandle, AOther.Handle) end; function TBLFontData.GetFaceCount: Integer; begin Result := FHandle.impl.faceCount; end; function TBLFontData.GetFaceType: TBLFontFaceType; begin Result := TBLFontFaceType(FHandle.impl.faceType); end; function TBLFontData.GetFlags: TBLFontDataFlags; begin Byte(Result) := FHandle.impl.flags; end; function TBLFontData.GetHandle: PBLFontDataCore; begin Result := @FHandle; end; function TBLFontData.GetIsCollection: Boolean; begin Result := ((FHandle.impl.flags and BL_FONT_DATA_FLAG_COLLECTION) <> 0); end; function TBLFontData.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLFontData.GetTags(const AFaceIndex: Integer): TArray; var Tags: IBLArray; begin Tags := TBLUtils.CreateBLArray; _BLCheck(blFontDataListTags(@FHandle, AFaceIndex, Tags.Handle)); Result := TBLUtils.BLArrayToArray(Tags); end; procedure TBLFontData.InitializeFromData(const AData: TBytes); var Data: IBLArray; begin if (AData <> nil) then begin Data := TBLUtils.ArrayToBLArray(AData); _BLCheck(blFontDataCreateFromDataArray(@FHandle, Data.Handle)); end; end; procedure TBLFontData.InitializeFromData(const AData: Pointer; const ASize: Integer; const AOnDestroy: TBLFontDataDestroyEvent); var DestroyFunc: BLDestroyImplFunc; DestroyData: PDestroyData; begin if Assigned(AOnDestroy) then begin DestroyFunc := DoDestroy; GetMem(DestroyData, SizeOf(TDestroyData)); DestroyData.FontData := Self; DestroyData.Event := AOnDestroy; end else begin DestroyFunc := nil; DestroyData := nil; end; _BLCheck(blFontDataCreateFromData(@FHandle, AData, ASize, DestroyFunc, DestroyData)); end; procedure TBLFontData.InitializeFromFile(const AFilename: String; const AReadFlags: TBLFileReadFlags); begin _BLCheck(blFontDataCreateFromFile(@FHandle, MarshaledAString(UTF8String(AFilename)), Byte(AReadFlags))); end; function TBLFontData.QueryTable(const AFaceIndex: Integer; const ATag: TBLTag; out ATable: TBLFontTable): Integer; begin Result := blFontDataQueryTables(@FHandle, AFaceIndex, @ATable.FHandle, @ATag, 1); end; function TBLFontData.QueryTables(const AFaceIndex: Integer; const ATags: TArray; out ATables: TArray): Integer; begin SetLength(ATables, Length(ATags)); Result := blFontDataQueryTables(@FHandle, AFaceIndex, Pointer(ATables), Pointer(ATags), Length(ATags)); end; procedure TBLFontData.Reset; begin _BLCheck(blFontDataReset(@FHandle)); end; { TBLFontFace } constructor TBLFontFace.Create; begin inherited; blFontFaceInit(@FHandle); end; constructor TBLFontFace.Create(const AHandle: BLFontFaceCore; const AIsReference: Boolean); begin inherited Create; FHandle := AHandle; FIsReference := AIsReference; end; destructor TBLFontFace.Destroy; begin if (not FIsReference) then blFontFaceDestroy(@FHandle); inherited; end; function TBLFontFace.Equals(const AOther: IBLFontFace): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := blFontFaceEquals(@FHandle, AOther.Handle) end; function TBLFontFace.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLFontFace) then Result := blFontFaceEquals(@FHandle, @TBLFontFace(Obj).FHandle) else Result := False; end; function TBLFontFace.GetData: IBLFontData; begin if (FData = nil) then FData := TBLFontData.Create(FHandle.impl.data, True); Result := FData; end; function TBLFontFace.GetDesignMetrics: TBLFontDesignMetrics; begin Result.FHandle := FHandle.impl.designMetrics; end; function TBLFontFace.GetDiagFlags: TBLFontFaceDiagFlags; begin Word(Result) := FHandle.impl.faceInfo.diagFlags; end; function TBLFontFace.GetFaceFlags: TBLFontFaceFlags; begin Cardinal(Result) := FHandle.impl.faceInfo.faceFlags; end; function TBLFontFace.GetFaceIndex: Integer; begin Result := FHandle.impl.faceInfo.faceIndex; end; function TBLFontFace.GetFaceInfo: TBLFontFaceInfo; begin Result.FHandle := FHandle.impl.faceInfo; end; function TBLFontFace.GetFaceType: TBLFontFaceType; begin Result := TBLFontFaceType(FHandle.impl.faceInfo.faceType); end; function TBLFontFace.GetFamilyName: String; var S: UTF8String; begin SetString(S, FHandle.impl.familyName.impl.data, FHandle.impl.familyName.impl.size); Result := String(S); end; function TBLFontFace.GetFullName: String; var S: UTF8String; begin SetString(S, FHandle.impl.fullName.impl.data, FHandle.impl.fullName.impl.size); Result := String(S); end; function TBLFontFace.GetHandle: PBLFontFaceCore; begin Result := @FHandle; end; function TBLFontFace.GetHasBaselineYAt0: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_BASELINE_Y_EQUALS_0) <> 0); end; function TBLFontFace.GetHasCharToGlyphMapping: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_CHAR_TO_GLYPH_MAPPING) <> 0); end; function TBLFontFace.GetHasHorizontalKerning: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_HORIZONTAL_KERNING) <> 0); end; function TBLFontFace.GetHasHorizontalMetrics: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_HORIZONTAL_METRICS) <> 0); end; function TBLFontFace.GetHasLSBPointXAt0: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_LSB_POINT_X_EQUALS_0) <> 0); end; function TBLFontFace.GetHasOpenTypeFeatures: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_OPENTYPE_FEATURES) <> 0); end; function TBLFontFace.GetHasOpenTypeVariations: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_OPENTYPE_VARIATIONS) <> 0); end; function TBLFontFace.GetHasPanoseData: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_PANOSE_DATA) <> 0); end; function TBLFontFace.GetHasTypographicMetrics: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_TYPOGRAPHIC_METRICS) <> 0); end; function TBLFontFace.GetHasTypographicNames: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_TYPOGRAPHIC_NAMES) <> 0); end; function TBLFontFace.GetHasUnicodeCoverage: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_UNICODE_COVERAGE) <> 0); end; function TBLFontFace.GetHasVariationSequences: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_VARIATION_SEQUENCES) <> 0); end; function TBLFontFace.GetHasVerticalKerning: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_VERTICAL_KERNING) <> 0); end; function TBLFontFace.GetHasVerticalMetrics: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_VERTICAL_METRICS) <> 0); end; function TBLFontFace.GetIsLastResortFont: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_LAST_RESORT_FONT) <> 0); end; function TBLFontFace.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLFontFace.GetIsSymbolFont: Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and BL_FONT_FACE_FLAG_SYMBOL_FONT) <> 0); end; function TBLFontFace.GetOutlineType: TBLFontOutlineType; begin Result := TBLFontOutlineType(FHandle.impl.faceInfo.outlineType); end; function TBLFontFace.GetPanose: TBLFontPanose; begin Result := TBLFontPanose(FHandle.impl.panose); end; function TBLFontFace.GetPostScriptName: String; var S: UTF8String; begin SetString(S, FHandle.impl.postScriptName.impl.data, FHandle.impl.postScriptName.impl.size); Result := String(S); end; function TBLFontFace.GetStretch: TBLFontStretch; begin Result := TBLFontStretch(FHandle.impl.stretch); end; function TBLFontFace.GetStyle: TBLFontStyle; begin Result := TBLFontStyle(FHandle.impl.style); end; function TBLFontFace.GetSubfamilyName: String; var S: UTF8String; begin SetString(S, FHandle.impl.subfamilyName.impl.data, FHandle.impl.subfamilyName.impl.size); Result := String(S); end; function TBLFontFace.GetUnicodeCoverage: TBLFontUnicodeCoverage; begin Result.FHandle := FHandle.impl.unicodeCoverage; end; function TBLFontFace.GetUniqueId: TBLUniqueId; begin Result := FHandle.impl.uniqueId; end; function TBLFontFace.GetUnitsPerEm: Integer; begin Result := FHandle.impl.designMetrics.unitsPerEm; end; function TBLFontFace.GetWeight: TBLFontWeight; begin Result := TBLFontWeight(FHandle.impl.weight); end; function TBLFontFace.HasFaceFlag(const AFlag: TBLFontFaceFlag): Boolean; begin Result := ((FHandle.impl.faceInfo.faceFlags and Ord(AFlag)) <> 0); end; procedure TBLFontFace.InitializeFromData(const AFontData: IBLFontData; const AFaceIndex: Integer); begin FData := AFontData; if (AFontData <> nil) then _BLCheck(blFontFaceCreateFromData(@FHandle, AFontData.Handle, AFaceIndex)); end; procedure TBLFontFace.InitializeFromFile(const AFilename: String; const AReadFlags: TBLFileReadFlags); begin _BLCheck(blFontFaceCreateFromFile(@FHandle, MarshaledAString(UTF8String(AFilename)), Byte(AReadFlags))); end; procedure TBLFontFace.Reset; begin _BLCheck(blFontFaceReset(@FHandle)); end; { TBLFont } procedure TBLFont.ApplyGPos(const AGlyphBuffer: IBLGlyphBuffer; const AIndex: Integer; const ALookups: TBLBitWord); begin if (AGlyphBuffer <> nil) then _BLCheck(blFontApplyGPos(@FHandle, AGlyphBuffer.Handle, AIndex, ALookups)); end; procedure TBLFont.ApplyGSub(const AGlyphBuffer: IBLGlyphBuffer; const AIndex: Integer; const ALookups: TBLBitWord); begin if (AGlyphBuffer <> nil) then _BLCheck(blFontApplyGSub(@FHandle, AGlyphBuffer.Handle, AIndex, ALookups)); end; procedure TBLFont.ApplyKerning(const AGlyphBuffer: IBLGlyphBuffer); begin if (AGlyphBuffer <> nil) then _BLCheck(blFontApplyKerning(@FHandle, AGlyphBuffer.Handle)); end; constructor TBLFont.Create; begin inherited; blFontInit(@FHandle); end; destructor TBLFont.Destroy; begin blFontDestroy(@FHandle); inherited; end; class function TBLFont.DoSink(path: PBLPathCore; info, closure: Pointer): Cardinal; var Font: TBLFont; begin Result := 0; if Assigned(closure) then begin Font := TBLFont(Closure); if Assigned(Font.FSink) then Result := Ord(Font.FSink(Font.FSinkPath, info)); end; end; function TBLFont.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLFont) then Result := blFontEquals(@FHandle, @TBLFont(Obj).FHandle) else Result := False; end; function TBLFont.Equals(const AOther: IBLFont): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := blFontEquals(@FHandle, AOther.Handle) end; function TBLFont.GetDesignMetrics: TBLFontDesignMetrics; begin Result.FHandle := FHandle.impl.face.impl.designMetrics; end; function TBLFont.GetFace: IBLFontFace; begin Result := FFace; end; function TBLFont.GetFaceFlags: TBLFontFaceFlags; begin Result := TBLFontFaceFlags(FHandle.impl.face.impl.faceInfo.faceFlags); end; function TBLFont.GetFaceType: TBLFontFaceType; begin Result := TBLFontFaceType(FHandle.impl.face.impl.faceInfo.faceType); end; function TBLFont.GetFeatures: TArray; begin Result := TBLUtils.BLArrayToArray(FHandle.impl.features); end; function TBLFont.GetGlyphAdvances(const AGlyphData: PCardinal; const AGlyphAdvance, ACount: Integer): TArray; begin SetLength(Result, ACount); _BLCheck(blFontGetGlyphAdvances(@FHandle, Pointer(AGlyphData), AGlyphAdvance, Pointer(Result), ACount)); end; function TBLFont.GetGlyphBounds(const AGlyphData: PCardinal; const AGlyphAdvance, ACount: Integer): TArray; begin SetLength(Result, ACount); _BLCheck(blFontGetGlyphBounds(@FHandle, Pointer(AGlyphData), AGlyphAdvance, Pointer(Result), ACount)); end; function TBLFont.GetGlyphOutlines(const AGlyphId: Cardinal; const AUserMatrix: TBLMatrix2D; const ASink: TBLPathSinkEvent): IBLPath; var Sink: BLPathSinkFunc; Closure: Pointer; begin Result := TBLPath.Create; if Assigned(ASink) then begin FSink := ASink; FSinkPath := Result; Sink := DoSink; Closure := Self; end else begin Sink := nil; Closure := nil; end; _BLCheck(blFontGetGlyphOutlines(@FHandle, AGlyphId, @AUserMatrix, Result.Handle, Sink, Closure)); end; function TBLFont.GetGlyphOutlines(const AGlyphId: Cardinal; const ASink: TBLPathSinkEvent): IBLPath; var Sink: BLPathSinkFunc; Closure: Pointer; begin Result := TBLPath.Create; if Assigned(ASink) then begin FSink := ASink; FSinkPath := Result; Sink := DoSink; Closure := Self; end else begin Sink := nil; Closure := nil; end; _BLCheck(blFontGetGlyphOutlines(@FHandle, AGlyphId, nil, Result.Handle, Sink, Closure)); end; function TBLFont.GetGlyphRunOutlines(const AGlyphRun: TBLGlyphRun; const AUserMatrix: TBLMatrix2D; const ASink: TBLPathSinkEvent): IBLPath; var Sink: BLPathSinkFunc; Closure: Pointer; begin Result := TBLPath.Create; if Assigned(ASink) then begin FSink := ASink; FSinkPath := Result; Sink := DoSink; Closure := Self; end else begin Sink := nil; Closure := nil; end; _BLCheck(blFontGetGlyphRunOutlines(@FHandle, @AGlyphRun, @AUserMatrix, Result.Handle, Sink, Closure)); end; function TBLFont.GetGlyphRunOutlines(const AGlyphRun: TBLGlyphRun; const ASink: TBLPathSinkEvent): IBLPath; var Sink: BLPathSinkFunc; Closure: Pointer; begin Result := TBLPath.Create; if Assigned(ASink) then begin FSink := ASink; FSinkPath := Result; Sink := DoSink; Closure := Self; end else begin Sink := nil; Closure := nil; end; _BLCheck(blFontGetGlyphRunOutlines(@FHandle, @AGlyphRun, nil, Result.Handle, Sink, Closure)); end; function TBLFont.GetHandle: PBLFontCore; begin Result := @FHandle; end; function TBLFont.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLFont.GetMatrix: TBLFontMatrix; begin Result.FHandle := FHandle.impl.matrix; end; function TBLFont.GetMetrics: TBLFontMetrics; begin Result.FHandle := FHandle.impl.metrics; end; function TBLFont.GetMetricsPtr: PBLFontMetrics; begin Result := @FHandle.impl.metrics; end; function TBLFont.GetSize: Single; begin Result := FHandle.impl.metrics.size; end; function TBLFont.GetStretch: TBLFontStretch; begin Result := TBLFontStretch(FHandle.impl.stretch); end; function TBLFont.GetStyle: TBLFontStyle; begin Result := TBLFontStyle(FHandle.impl.style); end; function TBLFont.GetTextMetrics( const AGlyphBuffer: IBLGlyphBuffer): TBLTextMetrics; begin if (AGlyphBuffer <> nil) then _BLCheck(blFontGetTextMetrics(@FHandle, AGlyphBuffer.Handle, @Result.FHandle)); end; function TBLFont.GetUnitsPerEm: Integer; begin Result := FHandle.impl.face.impl.designMetrics.unitsPerEm; end; function TBLFont.GetVariations: TArray; begin Result := TBLUtils.BLArrayToArray(FHandle.impl.variations); end; function TBLFont.GetWeight: TBLFontWeight; begin Result := TBLFontWeight(FHandle.impl.weight); end; procedure TBLFont.InitializeFromFace(const AFace: IBLFontFace; const ASize: Single); begin if (AFace <> nil) then _BLCheck(blFontCreateFromFace(@FHandle, AFace.Handle, ASize)); end; procedure TBLFont.MapTextToGlyphs(const AGlyphBuffer: IBLGlyphBuffer); begin if (AGlyphBuffer <> nil) then _BLCheck(blFontMapTextToGlyphs(@FHandle, AGlyphBuffer.Handle, nil)); end; procedure TBLFont.MapTextToGlyphs(const AGlyphBuffer: IBLGlyphBuffer; out AState: TBLGlyphMappingState); begin if (AGlyphBuffer <> nil) then _BLCheck(blFontMapTextToGlyphs(@FHandle, AGlyphBuffer.Handle, @AState.FHandle)); end; procedure TBLFont.PositionGlyphs(const AGlyphBuffer: IBLGlyphBuffer; const APositioningFlags: Cardinal); begin if (AGlyphBuffer <> nil) then _BLCheck(blFontPositionGlyphs(@FHandle, AGlyphBuffer.Handle, APositioningFlags)); end; procedure TBLFont.Reset; begin _BLCheck(blFontReset(@FHandle)); end; procedure TBLFont.Shape(const AGlyphBuffer: IBLGlyphBuffer); begin if (AGlyphBuffer <> nil) then _BLCheck(blFontShape(@FHandle, AGlyphBuffer.Handle)); end; {$ENDREGION 'Font'} {$REGION 'Font Manager'} { TBLFontManager } procedure TBLFontManager.AddFace(const AFace: IBLFontFace); begin if (AFace <> nil) then _BLCheck(blFontManagerAddFace(@FHandle, AFace.Handle)); end; constructor TBLFontManager.Create; begin inherited; _BLCheck(blFontManagerInit(@FHandle)); end; destructor TBLFontManager.Destroy; begin blFontManagerDestroy(@FHandle); inherited; end; function TBLFontManager.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLFontManager) then Result := blFontManagerEquals(@FHandle, @TBLFontManager(Obj).FHandle) else Result := False; end; function TBLFontManager.Equals(const AOther: IBLFontManager): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := blFontManagerEquals(@FHandle, AOther.Handle); end; function TBLFontManager.GetFaceCount: Integer; begin Result := blFontManagerGetFaceCount(@FHandle); end; function TBLFontManager.GetFamilyCount: Integer; begin Result := blFontManagerGetFamilyCount(@FHandle); end; function TBLFontManager.GetHandle: PBLFontManagerCore; begin Result := @FHandle; end; function TBLFontManager.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLFontManager.HasFace(const AFace: IBLFontFace): Boolean; begin if (AFace <> nil) then Result := blFontManagerHasFace(@FHandle, AFace.Handle) else Result := False; end; procedure TBLFontManager.Initialize; begin blFontManagerCreate(@FHandle); end; function TBLFontManager.QueryFace(const AName: String): IBLFontFace; var Name: UTF8String; Face: BLFontFaceCore; begin Name := UTF8String(AName); if (blFontManagerQueryFace(@FHandle, MarshaledAString(Name), Length(Name), nil, @Face) = BL_SUCCESS) then Result := TBLFontFace.Create(Face, True) else Result := nil; end; function TBLFontManager.QueryFace(const AName: String; const AProperties: TBLFontQueryProperties): IBLFontFace; var Name: UTF8String; Face: BLFontFaceCore; begin Name := UTF8String(AName); if (blFontManagerQueryFace(@FHandle, MarshaledAString(Name), Length(Name), @AProperties.FHandle, @Face) = BL_SUCCESS) then Result := TBLFontFace.Create(Face, True) else Result := nil; end; function TBLFontManager.QueryFacesByFamilyName( const AName: String): TArray; var Name: UTF8String; FaceArray: IBLArray; FaceHandles: TArray; I: Integer; begin Name := UTF8String(AName); FaceArray := TBLUtils.CreateBLArray; if (blFontManagerQueryFacesByFamilyName(@FHandle, MarshaledAString(Name), Length(Name), FaceArray.Handle) = BL_SUCCESS) then begin FaceHandles := TBLUtils.BLArrayToArray(FaceArray); SetLength(Result, Length(FaceHandles)); for I := 0 to Length(Result) - 1 do Result[I] := TBLFontFace.Create(FaceHandles[I], True); end else Result := nil; end; procedure TBLFontManager.Reset; begin _BLCheck(blFontManagerReset(@FHandle)); end; {$ENDREGION 'Font Manager'} {$REGION 'Pixel Converter'} { TBLPixelConverterOptions } function TBLPixelConverterOptions.GetGap: Integer; begin Result := FHandle.gap; end; function TBLPixelConverterOptions.GetOrigin: TBLPointI; begin Result.FHandle := FHandle.origin; end; procedure TBLPixelConverterOptions.SetGap(const AValue: Integer); begin FHandle.gap := AValue; end; procedure TBLPixelConverterOptions.SetOrigin(const AValue: TBLPointI); begin FHandle.origin := AValue.FHandle; end; { TBLPixelConverter } procedure TBLPixelConverter.Assign(const AOther: IBLPixelConverter); begin if Assigned(AOther) then _BLCheck(blPixelConverterAssign(@FHandle, AOther.Handle)); end; procedure TBLPixelConverter.ConvertRect(const ASrcData: Pointer; const ASrcStride: Integer; const ADstData: Pointer; const ADstStride, AWidth, AHeight: Integer; const AOptions: TBLPixelConverterOptions); begin _BLCheck(blPixelConverterConvert(@FHandle, ADstData, ADstStride, ASrcData, ASrcStride, AWidth, AHeight, @AOptions.FHandle)); end; procedure TBLPixelConverter.ConvertRect(const ASrcData: Pointer; const ASrcStride: Integer; const ADstData: Pointer; const ADstStride, AWidth, AHeight: Integer); begin _BLCheck(blPixelConverterConvert(@FHandle, ADstData, ADstStride, ASrcData, ASrcStride, AWidth, AHeight, nil)); end; procedure TBLPixelConverter.ConvertSpan(const ASrcData, ADstData: Pointer; const AWidth: Integer); begin _BLCheck(blPixelConverterConvert(@FHandle, ADstData, 0, ASrcData, 0, AWidth, 1, nil)); end; procedure TBLPixelConverter.ConvertSpan(const ASrcData, ADstData: Pointer; const AWidth: Integer; const AOptions: TBLPixelConverterOptions); begin _BLCheck(blPixelConverterConvert(@FHandle, ADstData, 0, ASrcData, 0, AWidth, 1, @AOptions.FHandle)); end; constructor TBLPixelConverter.Create; begin inherited; blPixelConverterInit(@FHandle); end; class function TBLPixelConverter.CreatePlatformConverter: IBLPixelConverter; var SrcFormat, DstFormat: TBLFormatInfo; begin Result := TBLPixelConverter.Create; SrcFormat := TBLFormat.PRGB32.Info; DstFormat := SrcFormat; {$IFNDEF MSWINDOWS} DstFormat.RedShift := SrcFormat.BlueShift; DstFormat.BlueShift := SrcFormat.RedShift; {$ENDIF} Result.Initialize(SrcFormat, DstFormat, [TBLPixelConverterCreateFlag.NoMultiStep]); end; destructor TBLPixelConverter.Destroy; begin blPixelConverterDestroy(@FHandle); inherited; end; function TBLPixelConverter.GetHandle: PBLPixelConverterCore; begin Result := @FHandle; end; function TBLPixelConverter.GetIsInitialized: Boolean; begin Result := (FHandle.internalFlags <> 0); end; procedure TBLPixelConverter.Initialize(const ASrcInfo, ADstInfo: TBLFormatInfo; const ACreateFlags: TBLPixelConverterCreateFlags); begin _BLCheck(blPixelConverterCreate(@FHandle, @ADstInfo.FHandle, @ASrcInfo.FHandle, Byte(ACreateFlags))); end; procedure TBLPixelConverter.Reset; begin _BLCheck(blPixelConverterReset(@FHandle)); end; {$ENDREGION 'Pixel Converter'} {$REGION 'Context'} { TBLContextCreateInfo } function TBLContextCreateInfo.GetFlags: TBLContextCreateFlags; begin Cardinal(Result) := FHandle.flags; end; procedure TBLContextCreateInfo.Reset; begin FillChar(FHandle, SizeOf(FHandle), 0); end; procedure TBLContextCreateInfo.SetFlags(const AValue: TBLContextCreateFlags); begin FHandle.flags := Cardinal(AValue); end; { TBLContextCookie } class operator TBLContextCookie.Equal(const ALeft, ARight: TBLContextCookie): Boolean; begin Result := ALeft.Equals(ARight); end; function TBLContextCookie.Equals(const AOther: TBLContextCookie): Boolean; begin Result := (FHandle.data[0] = AOther.FHandle.data[0]) and (FHandle.data[1] = AOther.FHandle.data[1]); end; function TBLContextCookie.GetIsEmpty: Boolean; begin Result := (FHandle.data[0] = 0) and (FHandle.data[1] = 0); end; class operator TBLContextCookie.NotEqual(const ALeft, ARight: TBLContextCookie): Boolean; begin Result := not ALeft.Equals(ARight); end; procedure TBLContextCookie.Reset(const AData0, AData1: UInt64); begin FHandle.data[0] := AData0; FHandle.data[1] := AData1; end; procedure TBLContextCookie.Reset(const AOther: TBLContextCookie); begin Self := AOther; end; procedure TBLContextCookie.Reset; begin Reset(0, 0); end; { TBLContextHints } function TBLContextHints.GetGradientQuality: TBLGradientQuality; begin Result := TBLGradientQuality(FHandle.gradientQuality); end; function TBLContextHints.GetPatternQuality: TBLPatternQuality; begin Result := TBLPatternQuality(FHandle.patternQuality); end; function TBLContextHints.GetRenderingQuality: TBLRenderingQuality; begin Result := TBLRenderingQuality(FHandle.renderingQuality); end; procedure TBLContextHints.SetGradientQuality(const AValue: TBLGradientQuality); begin FHandle.gradientQuality := Ord(AValue); end; procedure TBLContextHints.SetPatternQuality(const AValue: TBLPatternQuality); begin FHandle.patternQuality := Ord(AValue); end; procedure TBLContextHints.SetRenderingQuality(const AValue: TBLRenderingQuality); begin FHandle.renderingQuality := Ord(AValue); end; { TBLContextState } function TBLContextState.GetApproximationOptions: TBLApproximationOptions; begin Result.FHandle := FHandle.approximationOptions; end; function TBLContextState.GetCompOp: TBLCompOp; begin Result := TBLCompOp(FHandle.compOp); end; function TBLContextState.GetFillAlpha: Double; begin Result := FHandle.styleAlpha[BL_CONTEXT_OP_TYPE_FILL]; end; function TBLContextState.GetFillRule: TBLFillRule; begin Result := TBLFillRule(FHandle.fillRule); end; function TBLContextState.GetFillStyle: TBLStyleType; begin Result := TBLStyleType(FHandle.styleType[BL_CONTEXT_OP_TYPE_FILL]); end; function TBLContextState.GetHints: TBLContextHints; begin Result.FHandle := FHandle.hints; end; function TBLContextState.GetMetaMatrix: TBLMatrix2D; begin Result.FHandle := FHandle.metaMatrix; end; function TBLContextState.GetSavedStateCount: Integer; begin Result := FHandle.savedStateCount; end; function TBLContextState.GetStrokeOptions: TBLStrokeOptions; begin Result.FHandle := FHandle.strokeOptions; end; function TBLContextState.GetStrokeStyle: TBLStyleType; begin Result := TBLStyleType(FHandle.styleType[BL_CONTEXT_OP_TYPE_STROKE]); end; function TBLContextState.GetTargetImage: IBLImage; begin if (FHandle.targetImage = nil) then Result := nil else Result := TBLImage.Create(FHandle.targetImage^, True); end; function TBLContextState.GetTargetSize: TBLSize; begin Result := TBLSize(FHandle.targetSize); end; function TBLContextState.GetStrokeAlpha: Double; begin Result := FHandle.styleAlpha[BL_CONTEXT_OP_TYPE_STROKE]; end; function TBLContextState.GetUserMatrix: TBLMatrix2D; begin Result.FHandle := FHandle.userMatrix; end; { TBLContext } procedure TBLContext.BlitImage(const ADst: TBLPointI; const ASrc: IBLImage); begin _BLCheck(blContextBlitImageI(@FHandle, @ADst, ASrc.Handle, nil)); end; procedure TBLContext.BlitImage(const ADst: TBLRect; const ASrc: IBLImage); begin _BLCheck(blContextBlitScaledImageD(@FHandle, @ADst, ASrc.Handle, nil)); end; procedure TBLContext.BlitImage(const ADst: TBLPointI; const ASrc: IBLImage; const ASrcArea: TBLRectI); begin _BLCheck(blContextBlitImageI(@FHandle, @ADst, ASrc.Handle, @ASrcArea)); end; procedure TBLContext.BlitImage(const ADst: TBLPoint; const ASrc: IBLImage; const ASrcArea: TBLRectI); begin _BLCheck(blContextBlitImageD(@FHandle, @ADst, ASrc.Handle, @ASrcArea)); end; procedure TBLContext.BlitImage(const ADst: TBLPoint; const ASrc: IBLImage); begin _BLCheck(blContextBlitImageD(@FHandle, @ADst, ASrc.Handle, nil)); end; procedure TBLContext.BlitImage(const ADst: TBLRectI; const ASrc: IBLImage); begin _BLCheck(blContextBlitScaledImageI(@FHandle, @ADst, ASrc.Handle, nil)); end; procedure TBLContext.BlitImage(const ADst: TBLRect; const ASrc: IBLImage; const ASrcArea: TBLRectI); begin _BLCheck(blContextBlitScaledImageD(@FHandle, @ADst, ASrc.Handle, @ASrcArea)); end; procedure TBLContext.AfterConstruction; begin inherited; { Blend2D requires that floating-point calculations do not raise exceptions.} SetExceptionMask(exAllArithmeticExceptions); end; procedure TBLContext.BlitImage(const ADst: TBLRectI; const ASrc: IBLImage; const ASrcArea: TBLRectI); begin _BLCheck(blContextBlitScaledImageI(@FHandle, @ADst, ASrc.Handle, @ASrcArea)); end; procedure TBLContext.ClearAll; begin _BLCheck(blContextClearAll(@FHandle)); end; procedure TBLContext.ClearRect(const ARect: TBLRectI); begin _BLCheck(blContextClearRectI(@FHandle, @ARect)); end; procedure TBLContext.ClearRect(const ARect: TBLRect); begin _BLCheck(blContextClearRectD(@FHandle, @ARect)); end; procedure TBLContext.ClearRect(const AX, AY, AW, AH: Double); var R: TBLRect; begin R.Reset(AX, AY, AW, AH); _BLCheck(blContextClearRectD(@FHandle, @R)); end; procedure TBLContext.ClipToRect(const AX, AY, AW, AH: Double); var R: TBLRect; begin R.Reset(AX, AY, AW, AH); _BLCheck(blContextClipToRectD(@FHandle, @R)); end; procedure TBLContext.ClipToRect(const ARect: TBLRect); begin _BLCheck(blContextClipToRectD(@FHandle, @ARect)); end; procedure TBLContext.ClipToRect(const ARect: TBLRectI); begin _BLCheck(blContextClipToRectI(@FHandle, @ARect)); end; constructor TBLContext.Create; begin inherited Create; blContextInit(@FHandle); end; constructor TBLContext.Create(const ATarget: IBLImage); begin inherited Create; if (ATarget = nil) then blContextInit(@FHandle) else _BLCheck(blContextInitAs(@FHandle, ATarget.Handle, nil)); end; constructor TBLContext.Create(const ATarget: IBLImage; const ACreateInfo: TBLContextCreateInfo); begin inherited Create; if (ATarget = nil) then blContextInit(@FHandle) else _BLCheck(blContextInitAs(@FHandle, ATarget.Handle, @ACreateInfo.FHandle)); end; destructor TBLContext.Destroy; begin blContextDestroy(@FHandle); inherited; end; function TBLContext.Equals(Obj: TObject): Boolean; begin if (Obj = nil) then Result := (Self = nil) else if (Obj = Self) then Result := True else if (Obj is TBLContext) then Result := (FHandle.impl = TBLContext(Obj).FHandle.impl) else Result := False; end; function TBLContext.Equals(const AOther: IBLContext): Boolean; begin if (AOther = nil) then Result := (Self = nil) else Result := (FHandle.impl = AOther.Handle.impl) end; procedure TBLContext.FillAll; begin _BLCheck(blContextFillAll(@FHandle)); end; procedure TBLContext.FillBox(const AX0, AY0, AX1, AY1: Double); var Box: TBLBox; begin Box.Reset(AX0, AY0, AX1, AY1); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_BOXD, @Box)); end; procedure TBLContext.FillBox(const ABox: TBLBox); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_BOXD, @ABox)); end; procedure TBLContext.FillBox(const ABox: TBLBoxI); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_BOXI, @ABox)); end; procedure TBLContext.FillBoxArray(const ABoxes: PBLBox; const ACount: Integer); var View: TBLArrayView; begin View.Reset(ABoxes, ACount); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @View)); end; procedure TBLContext.FillBoxArray(const ABoxes: TArray); var View: TBLArrayView; begin View.Reset(Pointer(ABoxes), Length(ABoxes)); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @View)); end; procedure TBLContext.FillBoxArray(const ABoxes: TBLArrayView); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @ABoxes)); end; procedure TBLContext.FillBoxArray(const ABoxes: PBLBoxI; const ACount: Integer); var View: TBLArrayView; begin View.Reset(ABoxes, ACount); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @View)); end; procedure TBLContext.FillBoxArray(const ABoxes: TBLArrayView); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @ABoxes)); end; procedure TBLContext.FillBoxArray(const ABoxes: TArray); var View: TBLArrayView; begin View.Reset(Pointer(ABoxes), Length(ABoxes)); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @View)); end; procedure TBLContext.FillChord(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); var Chord: TBLArc; begin Chord.Reset(ACX, ACY, ARX, ARY, AStart, ASweep); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_CHORD, @Chord)); end; procedure TBLContext.FillChord(const ACX, ACY, AR, AStart, ASweep: Double); var Chord: TBLArc; begin Chord.Reset(ACX, ACY, AR, AStart, ASweep); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_CHORD, @Chord)); end; procedure TBLContext.FillChord(const AChord: TBLArc); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_CHORD, @AChord)); end; procedure TBLContext.FillCircle(const ACX, ACY, AR: Double); var Circle: TBLCircle; begin Circle.Reset(ACX, ACY, AR); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_CIRCLE, @Circle)); end; procedure TBLContext.FillCircle(const ACircle: TBLCircle); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_CIRCLE, @ACircle)); end; procedure TBLContext.FillEllipse(const AEllipse: TBLEllipse); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ELLIPSE, @AEllipse)); end; procedure TBLContext.FillEllipse(const ACX, ACY, ARX, ARY: Double); var Ellipse: TBLEllipse; begin Ellipse.Reset(ACX, ACY, ARX, ARY); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ELLIPSE, @Ellipse)); end; procedure TBLContext.FillGlyphRun(const ADst: TBLPoint; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); var Font: PBLFontCore; begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillGlyphRunD(@FHandle, @ADst, Font, @AGlyphRun)); end; procedure TBLContext.FillGlyphRun(const ADst: TBLPointI; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); var Font: PBLFontCore; begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillGlyphRunI(@FHandle, @ADst, Font, @AGlyphRun)); end; procedure TBLContext.FillGlyphRun(const ADst: TBLPoint; const AFont: IBLFont; const AGlyphRun: PBLGlyphRun); var Font: PBLFontCore; begin if (AGlyphRun <> nil) then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillGlyphRunD(@FHandle, @ADst, Font, Pointer(AGlyphRun))); end; end; procedure TBLContext.FillGlyphRun(const ADst: TBLPointI; const AFont: IBLFont; const AGlyphRun: PBLGlyphRun); var Font: PBLFontCore; begin if (AGlyphRun <> nil) then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillGlyphRunI(@FHandle, @ADst, Font, Pointer(AGlyphRun))); end; end; procedure TBLContext.FillPath(const APath: IBLPath); begin if (APath <> nil) then _BLCheck(blContextFillPathD(@FHandle, APath.Handle)); end; procedure TBLContext.FillPie(const ACX, ACY, AR, AStart, ASweep: Double); var Pie: TBLArc; begin Pie.Reset(ACX, ACY, AR, AStart, ASweep); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_PIE, @Pie)); end; procedure TBLContext.FillPie(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); var Pie: TBLArc; begin Pie.Reset(ACX, ACY, ARX, ARY, AStart, ASweep); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_PIE, @Pie)); end; procedure TBLContext.FillPie(const APie: TBLArc); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_PIE, @APie)); end; procedure TBLContext.FillPolygon(const APoly: TBLArrayView); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @APoly)); end; procedure TBLContext.FillPolygon(const APoly: TArray); var View: TBLArrayView; begin View.Reset(Pointer(APoly), Length(APoly)); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @View)); end; procedure TBLContext.FillPolygon(const APoly: TBLArrayView); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @APoly)); end; procedure TBLContext.FillPolygon(const APoly: PBLPointI; const ACount: Integer); var View: TBLArrayView; begin View.Reset(APoly, ACount); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @View)); end; procedure TBLContext.FillPolygon(const APoly: TArray); var View: TBLArrayView; begin View.Reset(Pointer(APoly), Length(APoly)); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @View)); end; procedure TBLContext.FillPolygon(const APoly: PBLPoint; const ACount: Integer); var View: TBLArrayView; begin View.Reset(APoly, ACount); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @View)); end; procedure TBLContext.FillRect(const AX, AY, AW, AH: Double); var R: TBLRect; begin R.Reset(AX, AY, AW, AH); _BLCheck(blContextFillRectD(@FHandle, @R)); end; procedure TBLContext.FillRect(const ARect: TBLRect); begin _BLCheck(blContextFillRectD(@FHandle, @ARect)); end; procedure TBLContext.FillRect(const ARect: TBLRectI); begin _BLCheck(blContextFillRectI(@FHandle, @ARect)); end; procedure TBLContext.FillRectArray(const ARects: PBLRect; const ACount: Integer); var View: TBLArrayView; begin View.Reset(ARects, ACount); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @View)); end; procedure TBLContext.FillRectArray(const ARects: TArray); var View: TBLArrayView; begin View.Reset(Pointer(ARects), Length(ARects)); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @View)); end; procedure TBLContext.FillRectArray(const ARects: TBLArrayView); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @ARects)); end; procedure TBLContext.FillRectArray(const ARects: TArray); var View: TBLArrayView; begin View.Reset(Pointer(ARects), Length(ARects)); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @View)); end; procedure TBLContext.FillRectArray(const ARects: TBLArrayView); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @ARects)); end; procedure TBLContext.FillRectArray(const ARects: PBLRectI; const ACount: Integer); var View: TBLArrayView; begin View.Reset(ARects, ACount); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @View)); end; procedure TBLContext.FillRegion(const ARegion: IBLRegion); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_REGION, ARegion.Handle)); end; procedure TBLContext.FillRoundRect(const ARect: TBLRect; const AR: Double); var RoundRect: TBLRoundRect; begin RoundRect.Reset(ARect, AR); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @RoundRect)); end; procedure TBLContext.FillRoundRect(const ARoundRect: TBLRoundRect); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @ARoundRect)); end; procedure TBLContext.FillRoundRect(const AX, AY, AW, AH, AR: Double); var RoundRect: TBLRoundRect; begin RoundRect.Reset(AX, AY, AW, AH, AR); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @RoundRect)); end; procedure TBLContext.FillRoundRect(const ARect: TBLRect; const ARX, ARY: Double); var RoundRect: TBLRoundRect; begin RoundRect.Reset(ARect, ARX, ARY); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @RoundRect)); end; procedure TBLContext.FillRoundRect(const AX, AY, AW, AH, ARX, ARY: Double); var RoundRect: TBLRoundRect; begin RoundRect.Reset(AX, AY, AW, AH, ARX, ARY); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @RoundRect)); end; procedure TBLContext.FillText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UTF8String); var Font: PBLFontCore; begin if (AText <> '') then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillTextI(@FHandle, @ADst, Font, Pointer(AText), Length(AText), BL_TEXT_ENCODING_UTF8)); end; end; procedure TBLContext.FillText(const ADst: TBLPoint; const AFont: IBLFont; const AText: String); var Font: PBLFontCore; begin if (AText <> '') then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillTextD(@FHandle, @ADst, Font, Pointer(AText), Length(AText), BL_TEXT_ENCODING_UTF16)); end; end; procedure TBLContext.FillText(const ADst: TBLPointI; const AFont: IBLFont; const AText: String); var Font: PBLFontCore; begin if (AText <> '') then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillTextI(@FHandle, @ADst, Font, Pointer(AText), Length(AText), BL_TEXT_ENCODING_UTF16)); end; end; procedure TBLContext.FillText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UCS4String); var Font: PBLFontCore; begin if (AText <> nil) then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillTextD(@FHandle, @ADst, Font, Pointer(AText), Length(AText) - 1, BL_TEXT_ENCODING_UTF32)); end; end; procedure TBLContext.FillText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UCS4String); var Font: PBLFontCore; begin if (AText <> nil) then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillTextI(@FHandle, @ADst, Font, Pointer(AText), Length(AText) - 1, BL_TEXT_ENCODING_UTF32)); end; end; procedure TBLContext.FillText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UTF8String); var Font: PBLFontCore; begin if (AText <> '') then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextFillTextD(@FHandle, @ADst, Font, Pointer(AText), Length(AText), BL_TEXT_ENCODING_UTF8)); end; end; procedure TBLContext.FillTriangle(const AX0, AY0, AX1, AY1, AX2, AY2: Double); var Triangle: TBLTriangle; begin Triangle.Reset(AX0, AY0, AX1, AY1, AX2, AY2); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_TRIANGLE, @Triangle)); end; procedure TBLContext.FillTriangle(const ATriangle: TBLTriangle); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_TRIANGLE, @ATriangle)); end; procedure TBLContext.Finish; begin _BLCheck(blContextEnd(@FHandle)); end; procedure TBLContext.Flush(const AFlags: TBLContextFlushFlags); begin _BLCheck(blContextFlush(@FHandle, Cardinal(AFlags))); end; function TBLContext.GetApproximationOptions: TBLApproximationOptions; begin Result.FHandle := FHandle.impl.state.approximationOptions; end; function TBLContext.GetCompOp: TBLCompOp; begin Result := TBLCompOp(FHandle.impl.state.compOp); end; function TBLContext.GetContextType: TBLContextType; begin Result := TBLContextType(FHandle.impl.contextType); end; function TBLContext.GetFillAlpha: Double; begin Result := FHandle.impl.state.styleAlpha[BL_CONTEXT_OP_TYPE_FILL]; end; function TBLContext.GetFillColor: TBLRgba32; var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); Result.Reset(TBLRgba(Style.rgba)); end; function TBLContext.GetFillColor64: TBLRgba64; var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); Result.Reset(TBLRgba(Style.rgba)); end; function TBLContext.GetFillColorF: TBLRgba; var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); Result := TBLRgba(Style.rgba); end; function TBLContext.GetFillGradient: IBLGradient; var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); Result := TBLGradient.Create(Style.gradient, True); end; function TBLContext.GetFillPattern: IBLPattern; var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); Result := TBLPattern.Create(Style.pattern, True); end; function TBLContext.GetFillRule: TBLFillRule; begin Result := TBLFillRule(FHandle.impl.state.fillRule); end; procedure TBLContext.GetFillStyle(out ARgba: TBLRgba32); var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); ARgba.Reset(TBLRgba(Style.rgba)); end; procedure TBLContext.GetFillStyle(out ARgba: TBLRgba64); var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); ARgba.Reset(TBLRgba(Style.rgba)); end; procedure TBLContext.GetFillStyle(out AGradient: IBLGradient); var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); AGradient := TBLGradient.Create(Style.gradient, True); end; procedure TBLContext.GetFillStyle(out ARgba: TBLRgba); var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); ARgba := TBLRgba(Style.rgba); end; procedure TBLContext.GetFillStyle(out APattern: IBLPattern); var Style: BLStyleCore; begin _BLCheck(blContextGetFillStyle(@FHandle, @Style)); APattern := TBLPattern.Create(Style.pattern, True); end; function TBLContext.GetFillStyle: TBLStyleType; begin Result := TBLStyleType(FHandle.impl.state.styleType[BL_CONTEXT_OP_TYPE_FILL]); end; function TBLContext.GetFlattenMode: TBLFlattenMode; begin Result := TBLFlattenMode(FHandle.impl.state.approximationOptions.flattenMode); end; function TBLContext.GetFlattenTolerance: Double; begin Result := FHandle.impl.state.approximationOptions.flattenTolerance; end; function TBLContext.GetGlobalAlpha: Double; begin Result := FHandle.impl.state.globalAlpha; end; function TBLContext.GetGradientQuality: TBLGradientQuality; begin Result := TBLGradientQuality(FHandle.impl.state.hints.gradientQuality); end; function TBLContext.GetHandle: PBLContextCore; begin Result := @FHandle; end; function TBLContext.GetHints: TBLContextHints; begin Result.FHandle := FHandle.impl.state.hints; end; function TBLContext.GetIsNone: Boolean; begin Result := ((FHandle.impl.implTraits and BL_IMPL_TRAIT_NULL) <> 0); end; function TBLContext.GetMetaMatrix: TBLMatrix2D; begin Result.FHandle := FHandle.impl.state.metaMatrix; end; function TBLContext.GetPatternQuality: TBLPatternQuality; begin Result := TBLPatternQuality(FHandle.impl.state.hints.patternQuality); end; function TBLContext.GetRenderingQuality: TBLRenderingQuality; begin Result := TBLRenderingQuality(FHandle.impl.state.hints.renderingQuality); end; function TBLContext.GetSavedStateCount: Integer; begin Result := FHandle.impl.state.savedStateCount; end; function TBLContext.GetStrokeAlpha: Double; begin Result := FHandle.impl.state.styleAlpha[BL_CONTEXT_OP_TYPE_STROKE]; end; function TBLContext.GetStrokeColor: TBLRgba32; var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); Result.Reset(TBLRgba(Style.rgba)); end; function TBLContext.GetStrokeColor64: TBLRgba64; var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); Result.Reset(TBLRgba(Style.rgba)); end; function TBLContext.GetStrokeColorF: TBLRgba; var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); Result := TBLRgba(Style.rgba); end; function TBLContext.GetStrokeDashArray: TArray; begin Result := TBLUtils.BLArrayToArray(FHandle.impl.state.strokeOptions.dashArray); end; function TBLContext.GetStrokeDashOffset: Double; begin Result := FHandle.impl.state.strokeOptions.dashOffset; end; function TBLContext.GetStrokeEndCap: TBLStrokeCap; begin Result := TBLStrokeCap(FHandle.impl.state.strokeOptions.options.endCap); end; function TBLContext.GetStrokeGradient: IBLGradient; var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); Result := TBLGradient.Create(Style.gradient, True); end; function TBLContext.GetStrokeJoin: TBLStrokeJoin; begin Result := TBLStrokeJoin(FHandle.impl.state.strokeOptions.options.join); end; function TBLContext.GetStrokeMiterLimit: Double; begin Result := FHandle.impl.state.strokeOptions.miterLimit; end; function TBLContext.GetStrokeOptions: TBLStrokeOptions; begin Result.FHandle := FHandle.impl.state.strokeOptions; end; function TBLContext.GetStrokePattern: IBLPattern; var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); Result := TBLPattern.Create(Style.pattern, True); end; function TBLContext.GetStrokeStartCap: TBLStrokeCap; begin Result := TBLStrokeCap(FHandle.impl.state.strokeOptions.options.startCap); end; procedure TBLContext.GetStrokeStyle(out ARgba: TBLRgba64); var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); ARgba.Reset(TBLRgba(Style.rgba)); end; procedure TBLContext.GetStrokeStyle(out ARgba: TBLRgba32); var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); ARgba.Reset(TBLRgba(Style.rgba)); end; procedure TBLContext.GetStrokeStyle(out AGradient: IBLGradient); var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); AGradient := TBLGradient.Create(Style.gradient, True); end; procedure TBLContext.GetStrokeStyle(out ARgba: TBLRgba); var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); ARgba := TBLRgba(Style.rgba); end; procedure TBLContext.GetStrokeStyle(out APattern: IBLPattern); var Style: BLStyleCore; begin _BLCheck(blContextGetStrokeStyle(@FHandle, @Style)); APattern := TBLPattern.Create(Style.pattern, True); end; function TBLContext.GetStrokeStyle: TBLStyleType; begin Result := TBLStyleType(FHandle.impl.state.styleType[BL_CONTEXT_OP_TYPE_STROKE]); end; function TBLContext.GetStrokeTransformOrder: TBLStrokeTransformOrder; begin Result := TBLStrokeTransformOrder(FHandle.impl.state.strokeOptions.options.transformOrder); end; function TBLContext.GetStrokeWidth: Double; begin Result := FHandle.impl.state.strokeOptions.width; end; function TBLContext.GetTargetHeight: Double; begin Result := FHandle.impl.state.targetSize.h; end; function TBLContext.GetTargetImage: IBLImage; begin if (FHandle.impl.state.targetImage = nil) then Result := nil else Result := TBLImage.Create(FHandle.impl.state.targetImage^, True); end; function TBLContext.GetTargetSize: TBLSize; begin Result.FHandle := FHandle.impl.state.targetSize; end; function TBLContext.GetTargetWidth: Double; begin Result := FHandle.impl.state.targetSize.w; end; function TBLContext.GetUserMatrix: TBLMatrix2D; begin Result.FHandle := FHandle.impl.state.userMatrix; end; procedure TBLContext.PostRotate(const AAngle: Double; const APoint: TBLPoint); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := APoint.FHandle.x; Data[2] := APoint.FHandle.y; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLContext.PostRotate(const AAngle: Double; const APoint: TBLPointI); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := APoint.FHandle.x; Data[2] := APoint.FHandle.y; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLContext.PostRotate(const AAngle: Double); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE, @AAngle)); end; procedure TBLContext.PostRotate(const AAngle, AX, AY: Double); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AX; Data[2] := AY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_ROTATE_PT, @Data)); end; procedure TBLContext.PostScale(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @Data)); end; procedure TBLContext.PostScale(const AXY: Double); var Data: array [0..1] of Double; begin Data[0] := AXY; Data[1] := AXY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @Data)); end; procedure TBLContext.PostScale(const APoint: TBLPoint); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @APoint)); end; procedure TBLContext.PostScale(const APoint: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := APoint.FHandle.x; Data[1] := APoint.FHandle.y; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SCALE, @Data)); end; procedure TBLContext.PostSkew(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SKEW, @Data)); end; procedure TBLContext.PostSkew(const APoint: TBLPoint); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_SKEW, @APoint)); end; procedure TBLContext.PostTransform(const AMatrix: TBLMatrix2D); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSFORM, @AMatrix)); end; procedure TBLContext.PostTranslate(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSLATE, @Data)); end; procedure TBLContext.PostTranslate(const APoint: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := APoint.FHandle.x; Data[1] := APoint.FHandle.y; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSLATE, @Data)); end; procedure TBLContext.PostTranslate(const APoint: TBLPoint); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_POST_TRANSLATE, @APoint)); end; function TBLContext.QueryAccumulatedErrorFlags: TBLContextErrorFlags; begin _BLCheck(blContextQueryProperty(@FHandle, BL_CONTEXT_PROPERTY_ACCUMULATED_ERROR_FLAGS, @Result)); end; function TBLContext.QueryThreadCount: Integer; begin _BLCheck(blContextQueryProperty(@FHandle, BL_CONTEXT_PROPERTY_THREAD_COUNT, @Result)); end; procedure TBLContext.Reset; begin _BLCheck(blContextReset(@FHandle)); end; procedure TBLContext.ResetMatrix; begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_RESET, nil)); end; procedure TBLContext.Restore(const ACookie: TBLContextCookie); begin _BLCheck(blContextRestore(@FHandle, @ACookie)); end; procedure TBLContext.Restore; begin _BLCheck(blContextRestore(@FHandle, nil)); end; procedure TBLContext.RestoreClipping; begin _BLCheck(blContextRestoreClipping(@FHandle)); end; procedure TBLContext.Rotate(const AAngle: Double; const APoint: TBLPoint); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := APoint.FHandle.x; Data[2] := APoint.FHandle.y; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLContext.Rotate(const AAngle, AX, AY: Double); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := AX; Data[2] := AY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLContext.Rotate(const AAngle: Double); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE, @AAngle)); end; procedure TBLContext.Rotate(const AAngle: Double; const APoint: TBLPointI); var Data: array [0..2] of Double; begin Data[0] := AAngle; Data[1] := APoint.FHandle.x; Data[2] := APoint.FHandle.y; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_ROTATE_PT, @Data)); end; procedure TBLContext.Save(out ACookie: TBLContextCookie); begin _BLCheck(blContextSave(@FHandle, @ACookie)); end; procedure TBLContext.Save; begin _BLCheck(blContextSave(@FHandle, nil)); end; procedure TBLContext.Scale(const AXY: Double); var Data: array [0..1] of Double; begin Data[0] := AXY; Data[1] := AXY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @Data)); end; procedure TBLContext.Scale(const APoint: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := APoint.FHandle.x; Data[1] := APoint.FHandle.y; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @Data)); end; procedure TBLContext.Scale(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @Data)); end; procedure TBLContext.Scale(const APoint: TBLPoint); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_SCALE, @APoint)); end; procedure TBLContext.SetCompOp(const AValue: TBLCompOp); begin _BLCheck(blContextSetCompOp(@FHandle, Ord(AValue))); end; procedure TBLContext.SetFillAlpha(const AValue: Double); begin _BLCheck(blContextSetFillAlpha(@FHandle, AValue)); end; procedure TBLContext.SetFillColor(const AValue: TBLRgba32); begin _BLCheck(blContextSetFillStyleRgba32(@FHandle, AValue.FHandle.value)); end; procedure TBLContext.SetFillColor64(const AValue: TBLRgba64); begin _BLCheck(blContextSetFillStyleRgba64(@FHandle, AValue.FHandle.value)); end; procedure TBLContext.SetFillColorF(const AValue: TBLRgba); begin _BLCheck(blContextSetFillStyleRgba(@FHandle, @AValue)); end; procedure TBLContext.SetFillGradient(const AValue: IBLGradient); begin if (AValue <> nil) then _BLCheck(blContextSetFillStyleObject(@FHandle, AValue.Handle)); end; procedure TBLContext.SetFillPattern(const AValue: IBLPattern); begin if (AValue <> nil) then _BLCheck(blContextSetFillStyleObject(@FHandle, AValue.Handle)); end; procedure TBLContext.SetFillRule(const AValue: TBLFillRule); begin _BLCheck(blContextSetFillRule(@FHandle, Ord(AValue))); end; procedure TBLContext.SetFillStyle(const ARgba: TBLRgba64); begin _BLCheck(blContextSetFillStyleRgba64(@FHandle, ARgba.FHandle.value)); end; procedure TBLContext.SetFillStyle(const ARgba: TBLRgba32); begin _BLCheck(blContextSetFillStyleRgba32(@FHandle, ARgba.FHandle.value)); end; procedure TBLContext.SetFillStyle(const APattern: IBLPattern); begin if (APattern <> nil) then _BLCheck(blContextSetFillStyleObject(@FHandle, APattern.Handle)); end; procedure TBLContext.SetFillStyle(const AImage: IBLImage); begin if (AImage <> nil) then _BLCheck(blContextSetFillStyleObject(@FHandle, AImage.Handle)); end; procedure TBLContext.SetFillStyle(const ARgba: TBLRgba); begin _BLCheck(blContextSetFillStyleRgba(@FHandle, @ARgba)); end; procedure TBLContext.SetFillStyle(const AGradient: IBLGradient); begin if (AGradient <> nil) then _BLCheck(blContextSetFillStyleObject(@FHandle, AGradient.Handle)); end; procedure TBLContext.SetFlattenMode(const AValue: TBLFlattenMode); begin _BLCheck(blContextSetFlattenMode(@FHandle, Ord(AValue))); end; procedure TBLContext.SetFlattenTolerance(const AValue: Double); begin _BLCheck(blContextSetFlattenTolerance(@FHandle, AValue)); end; procedure TBLContext.SetGlobalAlpha(const AValue: Double); begin _BLCheck(blContextSetGlobalAlpha(@FHandle, AValue)); end; procedure TBLContext.SetGradientQuality(const AValue: TBLGradientQuality); begin _BLCheck(blContextSetHint(@FHandle, BL_CONTEXT_HINT_GRADIENT_QUALITY, Ord(AValue))); end; procedure TBLContext.SetHints(const AValue: TBLContextHints); begin _BLCheck(blContextSetHints(@FHandle, @AValue.FHandle)); end; procedure TBLContext.SetPatternQuality(const AValue: TBLPatternQuality); begin _BLCheck(blContextSetHint(@FHandle, BL_CONTEXT_HINT_PATTERN_QUALITY, Ord(AValue))); end; procedure TBLContext.SetRenderingQuality(const AValue: TBLRenderingQuality); begin _BLCheck(blContextSetHint(@FHandle, BL_CONTEXT_HINT_RENDERING_QUALITY, Ord(AValue))); end; procedure TBLContext.SetStrokeAlpha(const AValue: Double); begin _BLCheck(blContextSetStrokeAlpha(@FHandle, AValue)); end; procedure TBLContext.SetStrokeColor(const AValue: TBLRgba32); begin _BLCheck(blContextSetStrokeStyleRgba32(@FHandle, AValue.FHandle.value)); end; procedure TBLContext.SetStrokeColor64(const AValue: TBLRgba64); begin _BLCheck(blContextSetStrokeStyleRgba64(@FHandle, AValue.FHandle.value)); end; procedure TBLContext.SetStrokeColorF(const AValue: TBLRgba); begin _BLCheck(blContextSetStrokeStyleRgba(@FHandle, @AValue)); end; procedure TBLContext.SetStrokeDashArray(const AValue: TArray); var Value: IBLArray; begin Value := TBLUtils.ArrayToBLArray(AValue); _BLCheck(blContextSetStrokeDashArray(@FHandle, Value.Handle)); end; procedure TBLContext.SetStrokeDashOffset(const AValue: Double); begin _BLCheck(blContextSetStrokeDashOffset(@FHandle, AValue)); end; procedure TBLContext.SetStrokeEndCap(const AValue: TBLStrokeCap); begin _BLCheck(blContextSetStrokeCap(@FHandle, BL_STROKE_CAP_POSITION_END, Ord(AValue))); end; procedure TBLContext.SetStrokeGradient(const AValue: IBLGradient); begin if (AValue <> nil) then _BLCheck(blContextSetStrokeStyleObject(@FHandle, AValue.Handle)); end; procedure TBLContext.SetStrokeJoin(const AValue: TBLStrokeJoin); begin _BLCheck(blContextSetStrokeJoin(@FHandle, Ord(AValue))); end; procedure TBLContext.SetStrokeMiterLimit(const AValue: Double); begin _BLCheck(blContextSetStrokeMiterLimit(@FHandle, AValue)); end; procedure TBLContext.SetStrokeOptions(const AValue: TBLStrokeOptions); begin _BLCheck(blContextSetStrokeOptions(@FHandle, @AValue.FHandle)); end; procedure TBLContext.SetStrokePattern(const AValue: IBLPattern); begin if (AValue <> nil) then _BLCheck(blContextSetStrokeStyleObject(@FHandle, AValue.Handle)); end; procedure TBLContext.SetStrokeStartCap(const AValue: TBLStrokeCap); begin _BLCheck(blContextSetStrokeCap(@FHandle, BL_STROKE_CAP_POSITION_START, Ord(AValue))); end; procedure TBLContext.SetStrokeStyle(const ARgba: TBLRgba64); begin _BLCheck(blContextSetStrokeStyleRgba64(@FHandle, ARgba.FHandle.value)); end; procedure TBLContext.SetStrokeStyle(const ARgba: TBLRgba32); begin _BLCheck(blContextSetStrokeStyleRgba32(@FHandle, ARgba.FHandle.value)); end; procedure TBLContext.SetStrokeStyle(const APattern: IBLPattern); begin if (APattern <> nil) then _BLCheck(blContextSetStrokeStyleObject(@FHandle, APattern.Handle)); end; procedure TBLContext.SetStrokeStyle(const AGradient: IBLGradient); begin if (AGradient <> nil) then _BLCheck(blContextSetStrokeStyleObject(@FHandle, AGradient.Handle)); end; procedure TBLContext.SetStrokeStyle(const AImage: IBLImage); begin if (AImage <> nil) then _BLCheck(blContextSetStrokeStyleObject(@FHandle, AImage.Handle)); end; procedure TBLContext.SetStrokeStyle(const ARgba: TBLRgba); begin _BLCheck(blContextSetStrokeStyleRgba(@FHandle, @ARgba)); end; procedure TBLContext.SetStrokeTransformOrder( const AValue: TBLStrokeTransformOrder); begin _BLCheck(blContextSetStrokeTransformOrder(@FHandle, Ord(AValue))); end; procedure TBLContext.SetStrokeWidth(const AValue: Double); begin _BLCheck(blContextSetStrokeWidth(@FHandle, AValue)); end; procedure TBLContext.SetUserMatrix(const AValue: TBLMatrix2D); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_ASSIGN, @AValue)); end; procedure TBLContext.Skew(const APoint: TBLPoint); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_SKEW, @APoint)); end; procedure TBLContext.Skew(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_SKEW, @Data)); end; procedure TBLContext.Start(const AImage: IBLImage; const ACreateInfo: TBLContextCreateInfo); begin if (AImage <> nil) then _BLCheck(blContextBegin(@FHandle, AImage.Handle, @ACreateInfo.FHandle)); end; procedure TBLContext.Start(const AImage: IBLImage); begin if (AImage <> nil) then _BLCheck(blContextBegin(@FHandle, AImage.Handle, nil)); end; procedure TBLContext.StrokeArc(const AArc: TBLArc); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ARC, @AArc)); end; procedure TBLContext.StrokeArc(const ACX, ACY, AR, AStart, ASweep: Double); var Arc: TBLArc; begin Arc.Reset(ACX, ACY, AR, AStart, ASweep); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ARC, @Arc)); end; procedure TBLContext.StrokeArc(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); var Arc: TBLArc; begin Arc.Reset(ACX, ACY, ARX, ARY, AStart, ASweep); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ARC, @Arc)); end; procedure TBLContext.StrokeBox(const AX0, AY0, AX1, AY1: Double); var Box: TBLBox; begin Box.Reset(AX0, AY0, AX1, AY1); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_BOXD, @Box)); end; procedure TBLContext.StrokeBox(const ABox: TBLBox); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_BOXD, @ABox)); end; procedure TBLContext.StrokeBox(const ABox: TBLBoxI); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_BOXI, @ABox)); end; procedure TBLContext.StrokeBoxArray(const ABoxes: PBLBoxI; const ACount: Integer); var View: TBLArrayView; begin View.Reset(ABoxes, ACount); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @View)); end; procedure TBLContext.StrokeBoxArray(const ABoxes: PBLBox; const ACount: Integer); var View: TBLArrayView; begin View.Reset(ABoxes, ACount); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @View)); end; procedure TBLContext.StrokeBoxArray(const ABoxes: TBLArrayView); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @ABoxes)); end; procedure TBLContext.StrokeBoxArray(const ABoxes: TBLArrayView); begin _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @ABoxes)); end; procedure TBLContext.StrokeBoxArray(const ABoxes: TArray); var View: TBLArrayView; begin View.Reset(Pointer(ABoxes), Length(ABoxes)); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, @View)); end; procedure TBLContext.StrokeBoxArray(const ABoxes: TArray); var View: TBLArrayView; begin View.Reset(Pointer(ABoxes), Length(ABoxes)); _BLCheck(blContextFillGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, @View)); end; procedure TBLContext.StrokeChord(const AChord: TBLArc); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_CHORD, @AChord)); end; procedure TBLContext.StrokeChord(const ACX, ACY, AR, AStart, ASweep: Double); var Chord: TBLArc; begin Chord.Reset(ACX, ACY, AR, AStart, ASweep); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_CHORD, @Chord)); end; procedure TBLContext.StrokeChord(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); var Chord: TBLArc; begin Chord.Reset(ACX, ACY, ARX, ARY, AStart, ASweep); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_CHORD, @Chord)); end; procedure TBLContext.StrokeCircle(const ACX, ACY, AR: Double); var Circle: TBLCircle; begin Circle.Reset(ACX, ACY, AR); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_CIRCLE, @Circle)); end; procedure TBLContext.StrokeCircle(const ACircle: TBLCircle); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_CIRCLE, @ACircle)); end; procedure TBLContext.StrokeEllipse(const AEllipse: TBLEllipse); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ELLIPSE, @AEllipse)); end; procedure TBLContext.StrokeEllipse(const ACX, ACY, ARX, ARY: Double); var Ellipse: TBLEllipse; begin Ellipse.Reset(ACX, ACY, ARX, ARY); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ELLIPSE, @Ellipse)); end; procedure TBLContext.StrokeGlyphRun(const ADst: TBLPointI; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); var Font: PBLFontCore; begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextStrokeGlyphRunI(@FHandle, @ADst, Font, @AGlyphRun)); end; procedure TBLContext.StrokeGlyphRun(const ADst: TBLPoint; const AFont: IBLFont; const AGlyphRun: TBLGlyphRun); var Font: PBLFontCore; begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextStrokeGlyphRunD(@FHandle, @ADst, Font, @AGlyphRun)); end; procedure TBLContext.StrokeLine(const AX0, AY0, AX1, AY1: Double); var Line: TBLLine; begin Line.Reset(AX0, AY0, AX1, AY1); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_LINE, @Line)); end; procedure TBLContext.StrokeLine(const AP0, AP1: TBLPoint); var Line: TBLLine; begin Line.Reset(AP0, AP1); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_LINE, @Line)); end; procedure TBLContext.StrokeLine(const ALine: TBLLine); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_LINE, @ALine)); end; procedure TBLContext.StrokePath(const APath: IBLPath); begin if (APath <> nil) then _BLCheck(blContextStrokePathD(@FHandle, APath.Handle)); end; procedure TBLContext.StrokePie(const ACX, ACY, ARX, ARY, AStart, ASweep: Double); var Pie: TBLArc; begin Pie.Reset(ACX, ACY, ARX, ARY, AStart, ASweep); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_PIE, @Pie)); end; procedure TBLContext.StrokePie(const ACX, ACY, AR, AStart, ASweep: Double); var Pie: TBLArc; begin Pie.Reset(ACX, ACY, AR, AStart, ASweep); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_PIE, @Pie)); end; procedure TBLContext.StrokePie(const APie: TBLArc); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_PIE, @APie)); end; procedure TBLContext.StrokePolygon(const APoly: TBLArrayView); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @APoly)); end; procedure TBLContext.StrokePolygon(const APoly: TArray); var View: TBLArrayView; begin View.Reset(Pointer(APoly), Length(APoly)); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @View)); end; procedure TBLContext.StrokePolygon(const APoly: PBLPoint; const ACount: Integer); var View: TBLArrayView; begin View.Reset(APoly, ACount); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @View)); end; procedure TBLContext.StrokePolygon(const APoly: TArray); var View: TBLArrayView; begin View.Reset(Pointer(APoly), Length(APoly)); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGOND, @View)); end; procedure TBLContext.StrokePolygon(const APoly: PBLPointI; const ACount: Integer); var View: TBLArrayView; begin View.Reset(APoly, ACount); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @View)); end; procedure TBLContext.StrokePolygon(const APoly: TBLArrayView); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYGONI, @APoly)); end; procedure TBLContext.StrokePolyline(const APoly: TBLArrayView); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINEI, @APoly)); end; procedure TBLContext.StrokePolyline(const APoly: TArray); var View: TBLArrayView; begin View.Reset(Pointer(APoly), Length(APoly)); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINED, @APoly)); end; procedure TBLContext.StrokePolyline(const APoly: TBLArrayView); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINED, @APoly)); end; procedure TBLContext.StrokePolyline(const APoly: PBLPoint; const ACount: Integer); var View: TBLArrayView; begin View.Reset(APoly, ACount); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINED, @APoly)); end; procedure TBLContext.StrokePolyline(const APoly: TArray); var View: TBLArrayView; begin View.Reset(Pointer(APoly), Length(APoly)); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINEI, @APoly)); end; procedure TBLContext.StrokePolyline(const APoly: PBLPointI; const ACount: Integer); var View: TBLArrayView; begin View.Reset(APoly, ACount); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_POLYLINEI, @APoly)); end; procedure TBLContext.StrokeRect(const ARect: TBLRectI); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_RECTI, @ARect)); end; procedure TBLContext.StrokeRect(const ARect: TBLRect); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_RECTD, @ARect)); end; procedure TBLContext.StrokeRect(const AX, AY, AW, AH: Double); var Rect: TBLRect; begin Rect.Reset(AX, AY, AW, AH); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_RECTD, @Rect)); end; procedure TBLContext.StrokeRectArray(const ARects: PBLRect; const ACount: Integer); var View: TBLArrayView; begin View.Reset(ARects, ACount); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @View)); end; procedure TBLContext.StrokeRectArray(const ARects: TArray); var View: TBLArrayView; begin View.Reset(Pointer(ARects), Length(ARects)); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @View)); end; procedure TBLContext.StrokeRectArray(const ARects: TBLArrayView); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, @ARects)); end; procedure TBLContext.StrokeRectArray(const ARects: TBLArrayView); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @ARects)); end; procedure TBLContext.StrokeRectArray(const ARects: PBLRectI; const ACount: Integer); var View: TBLArrayView; begin View.Reset(ARects, ACount); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @View)); end; procedure TBLContext.StrokeRectArray(const ARects: TArray); var View: TBLArrayView; begin View.Reset(Pointer(ARects), Length(ARects)); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, @View)); end; procedure TBLContext.StrokeRoundRect(const AX, AY, AW, AH, AR: Double); var RoundRect: TBLRoundRect; begin RoundRect.Reset(AX, AY, AW, AH, AR); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @RoundRect)); end; procedure TBLContext.StrokeRoundRect(const ARect: TBLRect; const AR: Double); var RoundRect: TBLRoundRect; begin RoundRect.Reset(ARect, AR); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @RoundRect)); end; procedure TBLContext.StrokeRoundRect(const ARoundRect: TBLRoundRect); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @ARoundRect)); end; procedure TBLContext.StrokeRoundRect(const ARect: TBLRect; const ARX, ARY: Double); var RoundRect: TBLRoundRect; begin RoundRect.Reset(ARect, ARX, ARY); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @RoundRect)); end; procedure TBLContext.StrokeRoundRect(const AX, AY, AW, AH, ARX, ARY: Double); var RoundRect: TBLRoundRect; begin RoundRect.Reset(AX, AY, AW, AH, ARX, ARY); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_ROUND_RECT, @RoundRect)); end; procedure TBLContext.StrokeText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UCS4String); var Font: PBLFontCore; begin if (AText <> nil) then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextStrokeTextD(@FHandle, @ADst, Font, Pointer(AText), Length(AText) - 1, BL_TEXT_ENCODING_UTF32)); end; end; procedure TBLContext.StrokeText(const ADst: TBLPoint; const AFont: IBLFont; const AText: UTF8String); var Font: PBLFontCore; begin if (AText <> '') then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextStrokeTextD(@FHandle, @ADst, Font, Pointer(AText), Length(AText), BL_TEXT_ENCODING_UTF8)); end; end; procedure TBLContext.StrokeText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UCS4String); var Font: PBLFontCore; begin if (AText <> nil) then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextStrokeTextI(@FHandle, @ADst, Font, Pointer(AText), Length(AText) - 1, BL_TEXT_ENCODING_UTF32)); end; end; procedure TBLContext.StrokeText(const ADst: TBLPointI; const AFont: IBLFont; const AText: UTF8String); var Font: PBLFontCore; begin if (AText <> '') then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextStrokeTextI(@FHandle, @ADst, Font, Pointer(AText), Length(AText), BL_TEXT_ENCODING_UTF8)); end; end; procedure TBLContext.StrokeText(const ADst: TBLPoint; const AFont: IBLFont; const AText: String); var Font: PBLFontCore; begin if (AText <> '') then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextStrokeTextD(@FHandle, @ADst, Font, Pointer(AText), Length(AText), BL_TEXT_ENCODING_UTF16)); end; end; procedure TBLContext.StrokeText(const ADst: TBLPointI; const AFont: IBLFont; const AText: String); var Font: PBLFontCore; begin if (AText <> '') then begin if (AFont = nil) then Font := nil else Font := AFont.Handle; _BLCheck(blContextStrokeTextI(@FHandle, @ADst, Font, Pointer(AText), Length(AText), BL_TEXT_ENCODING_UTF16)); end; end; procedure TBLContext.StrokeTriangle(const ATriangle: TBLTriangle); begin _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_TRIANGLE, @ATriangle)); end; procedure TBLContext.StrokeTriangle(const AX0, AY0, AX1, AY1, AX2, AY2: Double); var Triangle: TBLTriangle; begin Triangle.Reset(AX0, AY0, AX1, AY1, AX2, AY2); _BLCheck(blContextStrokeGeometry(@FHandle, BL_GEOMETRY_TYPE_TRIANGLE, @Triangle)); end; procedure TBLContext.Transform(const AMatrix: TBLMatrix2D); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSFORM, @AMatrix)); end; procedure TBLContext.Translate(const APoint: TBLPointI); var Data: array [0..1] of Double; begin Data[0] := APoint.FHandle.x; Data[1] := APoint.FHandle.y; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSLATE, @Data)); end; procedure TBLContext.Translate(const AX, AY: Double); var Data: array [0..1] of Double; begin Data[0] := AX; Data[1] := AY; _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSLATE, @Data)); end; procedure TBLContext.Translate(const APoint: TBLPoint); begin _BLCheck(blContextMatrixOp(@FHandle, BL_MATRIX2D_OP_TRANSLATE, @APoint)); end; procedure TBLContext.UserToMeta; begin _BLCheck(blContextUserToMeta(@FHandle)); end; {$ENDREGION 'Context'} {$REGION 'Runtime'} { TBLRuntimeBuildInfo } function TBLRuntimeBuildInfo.GetBaselineCpuFeatures: TBLRuntimeCpuFeatures; begin Byte(Result) := FHandle.baselineCpuFeatures; end; function TBLRuntimeBuildInfo.GetBuildType: TBLRuntimeBuildType; begin Result := TBLRuntimeBuildType(FHandle.buildType); end; function TBLRuntimeBuildInfo.GetSupportedCpuFeatures: TBLRuntimeCpuFeatures; begin Byte(Result) := FHandle.supportedCpuFeatures; end; { TBLRuntimeSystemInfo } function TBLRuntimeSystemInfo.GetCpuArch: TBLRuntimeCpuArch; begin Result := TBLRuntimeCpuArch(FHandle.cpuArch); end; function TBLRuntimeSystemInfo.GetCpuFeatures: TBLRuntimeCpuFeatures; begin Byte(Result) := FHandle.cpuFeatures; end; { TBLRuntime } class procedure TBLRuntime.Cleanup(const AFlags: TBLRuntimeCleanupFlags); begin _BLCheck(blRuntimeCleanup(Byte(AFlags))); end; class procedure TBLRuntime.LogMessage(const AMessage: String; const AArgs: array of const); begin _BLCheck(blRuntimeMessageOut(MarshaledAString(UTF8String(Format(AMessage, AArgs))))); end; class procedure TBLRuntime.LogMessage(const AMessage: String); begin _BLCheck(blRuntimeMessageOut(MarshaledAString(UTF8String(AMessage)))); end; class procedure TBLRuntime.QueryBuildInfo(out AInfo: TBLRuntimeBuildInfo); begin _BLCheck(blRuntimeQueryInfo(BL_RUNTIME_INFO_TYPE_BUILD, @AInfo)); end; class procedure TBLRuntime.QueryResourceInfo(out AInfo: TBLRuntimeResourceInfo); begin _BLCheck(blRuntimeQueryInfo(BL_RUNTIME_INFO_TYPE_RESOURCE, @AInfo)); end; class procedure TBLRuntime.QuerySystemInfo(out AInfo: TBLRuntimeSystemInfo); begin _BLCheck(blRuntimeQueryInfo(BL_RUNTIME_INFO_TYPE_SYSTEM, @AInfo)); end; {$ENDREGION 'Runtime'} {$REGION 'Internal'} procedure _BLCheck(const AResult: BLResultCode); begin if (AResult <> BL_SUCCESS) and Assigned(GErrorHandler) then GErrorHandler(TBLResultCode(AResult), GErrorUserData); end; {$ENDREGION 'Internal'} {$REGION 'Initialization'} initialization BLSetExceptionErrorHandler; {$ENDREGION 'Initialization'} end.