Archive for March, 2015

The Smart Pascal competition!

March 3, 2015 Leave a comment
Probably the coolest mini-pc in the world

Probably the coolest mini-pc in the world

I recently found myself in possession of probably the hottest piece of hardware on the market, the Raspberry PI 2 model B. This is the super funky version with roughly 10 times more speed than it’s predecessor, double the ram and more USB ports. It is capable of running Microsoft Windows 10 [ARM edition] when that arrives.

Well, now is the chance to win this puppy and have it sent to your doorstep!

Smart Mobile Studio

Back in 2012 Optimale Systemer AS held a Smart Mobile Studio competition where the winner got an iPad 2. And boy did we get some cool entries (!) Loads of classical 16 bit demo type projects which in my view is one of the best resources for beginners to learn from. The result is that Smart Mobile Studio ships with a ton of cool demo’s, ranging from phong shaded polyballs to high-quality WebGL landscape demonstrations.

While visual demonstrations are great, this competition is of a more serious type. Namely who can write the best Smart Mobile Studio custom-control!

Note: I must underline that this competition is not held by Optimale Systemer AS, but rather Delphi Developer, if you are not yet a member of our Facebook group, click the link and visit us!


  • No-one from the SMS team may enter the competition
  • You must be the author of the code you submit
  • External JS is allowed, but within reason (*1)
  • Write clean-cut, commented object pascal as much as possible
  • The code must be made open-source so others can learn from it
  • The control must make use of effects (*2)
  • Controls must conform to standard (*3)

*1: The goal here is Smart Pascal component writing, which means that JS is allowed but focus should be on providing a Smart Pascal solution. A thin wrapper around some external library is not really your creation. But we do allow the use of third party JavaScript libraries if their use can be justified.

*2: The w3effects.pas unit contains classes for triggering CSS transition effects. You can also edit the style-sheet and add your own CSS effects directly there. The use of tween.js is allowed, you may also use the Smart Pascal QTX library which makes effect programming child’s play. If effects are inappropriate for your particular controls, you may omit them naturally, but the goal should be to create controls With pleasant visual feedback when you interact with them. Also remember that CSS classes map directly to the control name. So if your control is called TMyControl, then a CSS class with the same name should be added to your stylesheet.

*3: With standards I am referring to ordinary control use, like overriding and deriving Your control from a valid visual ancestor (TW3CustomControl for instance). More than one Visual instance should be allowed on the form (unless the topic of your control dictates single instance use). No “special” (read: hack) way of initializing the control. Write a good one!


There are loads of cool JavaScript controls out there, ranging from the simple and elegant to the technically excellent. I strongly urge you to have a look at Chrome Experiments, which is a website dedicated to various effects and demonstrations for Chrome. Just remember that what this competition is about are controls. So it’s important to find something of value for others in their application design.

Coding controls is easy and fun!

Coding controls is easy and fun!

It could be something as simple as a HTML5 TPages (tab controls), a header control which animates it’s changes (e.g: you set backbutton.visible:=False and the button fades out rather than just vanish). Just have a look at TMS’s Delphi components for instance, which is very inspiring!

Or perhaps a 3D component? To achieve that have a look at our Sprite3d.pas unit which uses CSS to position ordinary DIV elements in 3D space. To add scene and perspective you must place them inside a container DIV with percentage size and perspective values — and voila, you have a 3D scene viewer component.

And last but not least, an old favorite of mine which I have implemented countless times in Delphi: The pixel editor control. With zoom, different drawing tools, grid, horizontal and vertical rules. It’s not hard to program but can be a little consuming once you get started.

Blast from the past component

Blast from the past component

Well — I have no intention of dictating what you should put into the competition, I write this only as a source of inspiration to provide some pointers as to what can be made.

If you havent written any Smart Mobile Studio controls before, dont worry. It’s a lot easier than native Delphi or FreePascal controls. Just inherit from TW3CustomControl, override InitializeObject (constructor) and FinalizeObject (destructor) and of-course ReSize() and you are well on you way. Just search this very blog for examples! The Smart RTL is rich in features, yet small and compact enough for expansion! You will notice how that Delphi 5 or 7 feeling comes back to you.

Just control-click your way around the RTL, just like you would in Delphi or Lazarus, and have a peek at the foundation classes. You will find it’s much smaller, easier to understand and ad-hoc than VCL or FMX.


Entries must be delivered by the 4 of April, so you have a whole month to complete this!

Note: If too few people enter I preserve the right to cancel the competition. At which point the Raspberry 2 will be given to the most impressive component-programmer so far.


The judges will be myself, Peter and Glenn over at Delphi Developer where we serve as administrators (Facebook group for Delphi, FreePascal and Smart Pascal developers). If you havent joined the coolest Delphi group in the universe you can do that here:


Send your submissions to lennart.aasenden AT gmail dot com, place “Smart competition” in the title!

ByteRage converted to Smart Pascal and JavaScript

March 1, 2015 Leave a comment

For a while now I’ve been thinking about re-creating one of my most used and low-level Delphi libraries, ByteRage, to Smart Pascal and JavaScript. But until now it’s not really been possible since JavaScript lacks any notion of memory, bytes or heaven forbid: pointers.

Well the other day I sat down and decided to sort this out, because in Smart Mobile Studio we have managed to re-create, implement and pretty much provide a full infrastructure for cutting edge application development — so why not bytes, steams, buffers and memory allocations? Well keep on reading and I’ll explain why. In detail.

But first; ByteRage has been successfully ported to Smart Mobile Studio ! If you want to know what all the fuzz is about and what ByteRage can do for you – then you can download the Delphi version here:

Byterage for Smart Pascal

You are probably wondering what this “byterage” library brings to the table. I mean, this is HTML5 after all. Well, first of all the basic concept of a buffer is what allows us to implement streams. But unlike our JavaScript friends we don’t cheat and just stuff your data into a string; pretending to support streams when we in fact just stuff things into strings. No I took on the task from the ground up and did it the proper way, using the browser API for buffers and typed arrays. And for all functions which have no browser-support, I implemented them using loop expansion for maximum speed.

As a result of this endeavour the Smart Mobile Studio RTL has gained a few units these past weeks, most notably System.Interop and SmartCL.Legacy. Which means you don’t have to download byterage for Smart Pascal, It’s now a part of Smart Mobile Studio and will ship with the next update.

Let’s have a peek at what System.Interop and SmartCL.legacy contains. I’ll also talk a bit about a few other important features I am adding to the next update (but rest assured, there is much much more in the update than this!).


This unit (short for system inter-operability) provides the fundamental byterage class: TBRBuffer (another name has been selected for the Smart RTL, but it’s essentially the same code). This is a class that fully manages a JavaScript UInt8Array, which is a typed array typically used for loading or storing binary data. For some odd reason JavaScript programmers seem to shun typed arrays so they are not yet widely used. Which is a bonus for us 🙂

What is unique about byterage buffers is:

  • It can scale without losing it’s content
  • Even large buffers can be serialized safely
  • Has a large number of export methods
  • Encodes and decodes all JavaScript datatypes to and from bytes
  • Provides bit manipulation for entire allocated buffer
  • Can be stored and loaded as JSON
  • .. and much more

First, the scaling: JavaScript UInt8Array’s don’t scale. They are allocated with a fixed size and once they are created their size remains. The only way to thus provide the ability to grow and shrink is to create a new UInt8Array, copy over the data from the previous and switch handle. Which is what my code does, very very quickly using loop expansion.

Next, Serialization. As you may know there is a time-limit involved in JavaScript execution. The idea is that if a JavaScript function call takes longer than X seconds, the JS VM aborts the call with an error. This means that JavaScript is hopeless at processing large heaps of data. To solve this, we process and serialize the buffer in chunks of 0x8000 bytes, allowing you to serialize megabytes of data if you so wish non-stop.

Exporting data from a buffer is imperative. As of writing the following export methods are available:

  • Array of Byte
  • Stream
  • Buffer clone
  • Buffer segment
  • UInt8Array clone
  • UInt8Array segment
  • JSON
  • Raw string

This should more than cover the export needs of getting data out of the buffer on byte-level. And naturally all export methods have a corresponding import function. So getting data back into a buffer is equally simple.

Next, encoding and decoding datatypes. Now this is a tricky one, and if you google the topic for JavaScript you will find many different solutions to the problem. Most of these solutions are either extremely complex, like breaking down a floating-point using math and bit-shifts alone. But they all have one thing in common – namely that they typically export as strings.

My code follows the JavaScript API and simply writes the data to a secondary memory buffer (the size of the datatype itself), then creates two different views into that buffer. One for byte access and one for the datatype in question (for instance a float view or an integer view). This is not only faster than any of the other experiments out there (read: “hacks”), it’s also fully valid and the way JavaScript buffers were designed to operate.

If you are curious about buffers and views you can have a peek at w3buffers.pas in the Smart RTL right now, it’s been a part of Smart Mobile Studio since the beginning. There you will find wrapper classes for the buffer-view mechanisms I have described above.

Then there is a novelty, namely bit manipulation. Now being able to set or get a bit inside a single integer or byte is handy, but it’s rare that it serves any real purpose. It’s only when you can treat a whole buffer as a collection of bits that things get interesting. Typically such “bit-maps” are used to keep track of open slots or re-cycle the use of a fixed set of elements. It can be a sprite-engine for a game which only can display 32 elements on-screen at once, or a database which needs to keep track of what pages are available inside a data-file. Either way, the buffer class provides full bit access on a global (buffer) scale.

Finally there is JSON, which is the de-facto storage format of the web. Buffers can both be stored and loaded in JSON format, and as mentioned I process the buffer in chunks, ensuring that JavaScript doesnt abort the call on large buffers.


As you have seen the fundamental buffer class is extremely versatile and provides pretty much everything you can ask for. You can read and write into a buffer at any offset, export it in a myriad of ways and even scale it. The only thing missing from the original Delphi byterage library, is the ability to insert data at any point in the buffer (as opposed to over-writing data). This is very handy for database work where you want to shrink (compact, compress) the database-file on occasion. Microsoft Access is a typical example, where calling “compress” removes empty pages from the file and re-organize records so pages are stored in-sequence inside the file.

So buffers are pretty cool!

On top of the buffer architecture I have implemented streams. Good old Delphi like streams, with TStreamReader and TStreamWriter classes to boot – allowing you to write into an advancing buffer (which is essentially the only difference between a buffer and a stream) just like you would do under FreePascal or Delphi. And the bonus is that the content of the streams on binary level, are identical to those produced with a “real” language. This means (as implied by the name “inter-operation”) that we can now share files between Delphi and Smart. If you have a custom file-format you want to bundle with your HTML5 applications you no longer need to pre-convert them to JSON. This is especially good news for RPC communication, like RemObjects SDK binary protocol which can finally be supported. Although I need to get LZH compression in here first.

Streams in combination with buffers opens up for a whole wealth of interesting communication between components as well. TW3Image can now load images directly from a stream. TW3Canvas now has a ToStream() function, allowing for 1:1 population of an on-screen image.

Streams makes us less dependent on the rules of the browser. For instance, implementing a PNG or JPG reader can now be done more or less exactly as it would be done in Delphi or C#. Although I would not recommend it for speed reasons – it’s now safely within the bounds of what can be achieved.

Perhaps you have a huge 3d mesh file you want to use with OpenGL? Stored in binary format you say? 64bit floating point? Well that’s no longer an issue. Just load the data into a stream and start reading the values, just like you would any other native language.


One of the mistakes I did when writing the original Smart Pascal RTL, was to sculpt TW3Canvas according to HTML5. I should in fact have re-created good old TCanvas from Delphi, juiced it up with all the cool new functions HTML5 provides – and made that the de-facto standard canvas.

I hardly think there has been a question so frequently asked as “how to I draw graphics in Smart Mobile Studio”. People coming straight from Delphi or FreePascal/Lazarus are so adjusted to TCanvas that the new HTML5 canvas comes across as alien. So in a perfect world I could go back in time 4 years and do that part over again, but sadly that is not possible.

The legacy unit intends to change all that. It provides a re-implementation of good old TCanvas. So if you find yourself porting over Delphi code or just want to play around with HTML5 and see what Smart Pascal can do, then you will enjoy this unit wholeheartedly. Whenever you need to draw graphics you can now use TBitmap and TCanvas just like under Delphi.

So you get these old gems out of the box:

  • TCanvas
  • TPen
  • TBrush
  • TPaintObject
  • TBitmap

Just to underline: one of the cool things about the HTML5 canvas, is that you can use any image as your pencil. This is also possible under Win32 using Delphi’s TCanvas, but you have to create a custom brush, select that into the device context, then put back the old system brush after your operation (as well as many more steps). So understandably very few programmers bother doing this and opt for a third-party graphics library instead (like Graphics32 or ImageEN).

Well in my TCanvas implementation such technique is not quite so horrendous. Simply assign a picture to Canvas.Brush or Canvas.Pen, both objects exposes a property called BitmapPattern for this exact purpose. Voila! When you use one of the drawing operations your image will be used as the brush. This can be augmented for spectacular effects. Just look at some of those JavaScript 10Kb demo’s and be amazed!

SmartCL.Legacy will no doubt grow, especially now that we have streams under wrap. I will try to port over as much of classical object pascal as I can, one class at a time.

Font measurement

You may not believe this but HTML5, neither the canvas nor the DOM, comes with proper font measurement! You have one rudimentary function, but having to create a graphics context and a canvas object just to measure the size of a text is ridicules. So I decided to do something about that as well.

For those of you that follow my blog I’m sure you remember the “Fonts once and for all” post a while back? Well in short I created the means of measuring fonts, which was one hell of a challenge. But now that the QTX library is being merged with the Smart RTL you will be able to enjoy that as well.

SmartCL.Fonts have been given a full overhaul and now includes a class named TW3FontDetector which takes care of business.

Note: You don’t create an instance of this class to measure text. The class indexes the browser’s fonts and families which takes a few milliseconds, so you don’t want to create an instance every time you need this. Instead, you simply access the unit-function “W3FontDetector” which returns an instance which is automatically created when your application starts.

So for measuring a piece of text you would write something like:

 var mSize:TW3TextMetric;
 mSize:=W3FontDetector.MeasureText("verdana",12,"this is my text here");

Now here comes the cool part: Access to font measurement has now been built into TW3CustomControl! When you use the methods in TW3CustomControl (which means the font measurement stuff is available almost anywhere) you don’t have to populate the font-name and pixel-size, the component will find out what font is selected into the element and it’s size automatically.
So finally calculating content size, element height and so on for your custom-controls is a walk in the park.

Which is another thing TW3FontDetector does. JavaScript and the DOM doesn’t have a clear-cut way of figuring out what font is selected into a DIV. In fact, several fonts can be selected into the same element – and the browser picks one of them when it builds its calculated-style (which is the stylesheet the browser actually uses when rendering). Well, if you need to figure out just what font is selected into a control, just call W3FontDetector.getFontInfo() and you get the info you need.


Here is a peek-preview of the interop unit’s interface:


  (* Byte should really be implemented on compiler level, but until we
     have that under wraps, we introduce it here as an integer type *)
  Byte = Integer;
  TByteArray = Array of Byte;

  (* TW3ByteHelper provides some handy helper functions for working with
     bytes. Turning a byte-value into a character is a nice method,
     and also Ensure() which claps the byte-value within 0..255. *)
  TW3ByteHelper = Helper for Byte
    function  ToBitMask:String;
    function  ToHex:String;
    function  Ensure:Byte;

  (* Forward declarations *)
  TStreamWriter   = Class;
  TStreamReader   = Class;
  TMemoryStream   = Class;
  TStream         = Class;
  TW3MemoryBuffer = Class;

  (* TW3MemoryBuffer:
     This class introduces a dynamically allocated UInt8Array which is
     completely maintained.

     * All operations are optimized with loop-expansion for maximum speed.
     * Buffer can grow without losing content (in-place duplication)
     * Buffer can shrink without loss of content (in-place duplication)
     * Append methods, also from another buffer or a free-standing THandle

     The bytebuffer is Smart Mobile Studio's absolute lowest level of
     data, as it represents an array of "real" bytes.
     Such data-buffers are common throughout HTML5, from the canvas pixel-data
     to the content of an image-tag.

     Being able to work with low-level data under JavaScript gives us an
     edge, since very few programmers tend to venture into this region
     of JavaScript. It opens up for many posebilities:
      * Zip support
      * Encryption
      * Binary transport of data between objects
      * .. Much, much more *)

  EW3MemoryBuffer = Class(EW3Exception);

  TW3BufferHexDumpOptions = set of (doSign,doZeroPad);

  TW3MemoryBuffer = Class(TObject)
    Fhandle:  THandle;
    function  getHandle:THandle;
    function  getSize:Integer;virtual;
    function  getByte(const Index:Integer):Byte;
    procedure setByte(const Index:Integer;const Value:Byte);
    function  OffsetInRange(Offset:Integer):Boolean;
    property  Handle:THandle read getHandle;
    Property  Size:Integer read getSize;
    Property  BitCount:Integer read (getSize * 8);

    Property  Bytes[const index:Integer]:Byte
              read getByte write setByte;default;

    Procedure Grow(const ByAmount:Integer);
    procedure Shrink(const ByAmount:Integer);

    Procedure Append(const Bytes:Array of Byte);overload;
    Procedure Append(const Text:String);overload;
    Procedure Append(Const Buffer:TW3MemoryBuffer;
    Procedure Append(Const Value:Float);overload;
    Procedure Append(Const Raw:THandle);overload;

    Procedure CopyFrom(Buffer:TW3MemoryBuffer;

    Procedure CopyFrom(Raw:THandle;

    function  &ExportBuffer(Offset:Integer;

    function  &ExportStream(Offset:Integer;

    Procedure Write(Offset:Integer;

    Procedure Write(Offset:Integer;Data:THandle);overload;
    Procedure Write(Offset:Integer;Data:String);overload;
    Procedure Write(Offset:Integer;Data:Integer);overload;
    procedure Write(Offset:Integer;Data:Float);Overload;
    procedure Write(Offset:Integer;Data:TByteArray);Overload;
    procedure Write(Offset:Integer;Data:Boolean);overload;

    function  ReadBool(Offset:Integer):Boolean;Overload;
    function  ReadFloat(Offset:Integer):Float;overload;
    function  ReadInt(Offset:Integer):Integer;overload;
    function  ReadStr(Offset:Integer;ByteLen:Integer):String;overload;
    function  ReadBytes(Offset:Integer;ByteLen:Integer):TByteArray;overload;

    function  Clone:TW3MemoryBuffer;

    function  ToBase64:String;
    function  ToString:String;
    function  ToRaw:THandle;
    function  ToBytes:TByteArray;
    function  ToHexDump(BytesPerRow:Integer;
    function  ToStream:TStream;

    procedure Allocate(const ByteSize:Integer);overload;
    Procedure Allocate(const Values:Array of Byte);overload;
    procedure Release;

    procedure setBit(bitIndex:Integer;const value:Boolean);
    function  getBit(bitIndex:Integer):Boolean;

    class function  StrToBase64(Value:String):String;
    class function  Base64ToStr(Value:String):String;

    class function  ByteToChar(Const Value:Byte):String;
    class function  CharToByte(const Value:String):Byte;

    Constructor Create(aHandle:THandle);virtual;
    Destructor  Destroy;Override;

  TW3StreamOrientation = (soFromStart,soFromCurrent);

  IStreamAccess = Interface
    function  getBuffer:TW3MemoryBuffer;
    function  getPosition:Integer;
    procedure setPosition(Offset:Integer);
    procedure Advance(Bytes:Integer);

  TStream = Class(TObject,IStreamAccess)
    function  getBuffer:TW3MemoryBuffer;virtual;abstract;
    function  getHandle:THandle;virtual;abstract;
    function  getSize:Integer;virtual;abstract;
    function  getPosition:Integer;virtual;abstract;
    procedure setPosition(Offset:Integer);virtual;abstract;
    procedure Advance(Bytes:Integer);virtual;abstract;
    Property  Handle:THandle read getHandle;
    Property  Size:Integer read getSize;
    Property  Position:Integer read getPosition write setPosition;

    function  CreateReader:TStreamReader;
    function  CreateWriter:TStreamWriter;

    function  ToBuffer:TW3MemoryBuffer;

    function  Read(ByteLen:Integer):TByteArray;virtual;abstract;
    procedure Write(Const Data:TByteArray);virtual;abstract;
    function  CopyFrom(source:TStream;ByteLen:Integer):Integer;
    procedure Seek(aDistance:Integer;Orientation:TW3StreamOrientation);

  TMemoryStream = Class(TStream)
    FBuffer:      TW3memoryBuffer;
    FPosition:    Integer;
    procedure     Advance(Bytes:Integer);override;
    function      getBuffer:TW3MemoryBuffer;override;
    function      getHandle:THandle;override;
    function      getSize:Integer;override;
    function      getPosition:Integer;override;
    procedure     setPosition(Offset:Integer);override;
    function      Read(ByteLen:Integer):TByteArray;override;
    procedure     Write(Const Data:TByteArray);override;
    Constructor   Create;virtual;
    Destructor    Destroy;Override;

  TStreamWriter = Class(TObject)
    FStream:    TStream;
    FAccess:    IStreamAccess;
    property    Stream:TStream read FStream;
    Property    Access:IStreamAccess read FAccess;
    procedure   WriteInteger(Const Value:Integer);virtual;
    procedure   WriteString(Const Value:String);virtual;
    procedure   WriteBoolean(Const Value:Boolean);virtual;
    Procedure   WriteFloat(Const Value:Float);virtual;
    Constructor Create(AStream:TStream);virtual;

  TStreamReader = Class(TObject)
    FStream:    TStream;
    FAccess:    IStreamAccess;
    property    Stream:TStream read FStream;
    Property    Access:IStreamAccess read FAccess;
    function    ReadInteger:Integer;virtual;
    function    ReadString(aLength:Integer):String;virtual;
    function    ReadBoolean:Boolean;virtual;
    function    ReadFloat:Float;virtual;
    Constructor Create(AStream:TStream);virtual;

And what would the world be without a preview of the legacy unit:

  (* This unit provides legacy support for Delphi/FreePascal TCanvas
     class. Although highly extended.

      -- Both Brush and Pen support bitmap patters for drawing
      -- Stroke must be called to realize graphics operations

  TBrushStyle = (

  TPenStyle = (

  TCanvas = Class;

  TCanvasPatternRepeatMode = (prRepeat,prRepeatX,prRepeatY,prNoRepeat);

  TPaintObject = Class(TW3OwnedObject)
    FBitmap:    TW3Image;
    FPattern:   JCanvasPattern;
    FRepeat:    TCanvasPatternRepeatMode;
    function    getFillStyle:THandle;virtual;
    procedure   setRepeat(Value:TCanvasPatternRepeatMode);virtual;
    Property    BitmapPattern:TCanvasPatternRepeatMode
                read FRepeat write setRepeat;
    Property    Bitmap:TW3Image read FBitmap;
    property    Color:TColor;
    Procedure   Clear;virtual;
    Constructor Create(AOwner:TCanvas);reintroduce;virtual;
    Destructor  Destroy;Override;

  TBrush  = Class(TPaintObject)
    Property    Style:TBrushStyle;
    Constructor Create(AOwner:TCanvas);override;

  TPen = Class(TPaintObject)
    Property    Mode:TPenStyle;
    Property    Width:Integer;
    Constructor Create(AOwner:TCanvas);override;

  TCanvas = Class(TObject)
    FContext:   TW3CustomGraphicContext;
    FBrush:     TBrush;
    FPen:       TPen;
    FDC:        JCanvasRenderingContext2D;
    FTempPxl:   TW3ImageData;
    FPos:       TPoint;
    FBounds:    TRect;
    FWidth:     Integer;
    FHeight:    Integer;
    function    getPixelDataBuffer:TW3ImageData;
    function    getValidPoint(const dx,dy:Integer):Boolean;

    function    getPixel(const x,y:Integer):TColor;
    procedure   setPixel(const x,y:Integer;const value:TColor);
    function    getPixelData(const x,y:Integer):TW3RGBA;
    procedure   setPixelData(const x,y:Integer;const value:TW3RGBA);
    function    getR(const x,y:Integer):Byte;
    function    getG(const x,y:Integer):Byte;
    function    getB(const x,y:Integer):Byte;
    function    getA(const x,y:Integer):Byte;
    Property    Width:Integer read FWidth;
    property    Height:Integer read FHeight;
    Property    BoundsRect:TRect read FBounds;
    Property    Context:TW3CustomGraphicContext read FContext;
    Property    Brush:TBrush read FBrush;
    property    Pen:TPen read FPen;

    Property    Pixels[const x,y:Integer]:TColor
                read getPixel write setPixel;

    Property    R[const x,y:Integer]:Byte read getR;
    Property    G[const x,y:Integer]:Byte read getG;
    property    B[const x,y:Integer]:Byte read getB;
    property    A[const x,y:Integer]:Byte read getA;

    Property    PixelData[const x,y:Integer]:TW3RGBA
                read getPixelData write setPixelData;

    Procedure   MoveTo(const dx,dy:Integer);
    procedure   LineTo(const dx,dy:Integer);

    procedure   Line(const x1,y1,x2,y2:Integer);overload;
    procedure   Line(const x1,y1,x2,y2:Float);overload;

    Procedure   Hline(const x1,y1,width:Integer);
    Procedure   VLine(const x1,y1,Height:Integer);

    Procedure   Rectangle(const aRect:TRect);overload;
    procedure   Rectangle(const x1,y1,x2,y2:Integer);overload;

    Procedure   FillRect(const aRect:TRect);overload;
    procedure   FillRect(const x1,y1,x2,y2:Integer);overload;

    function    ToDataURL(aMimeType: String): String;
    function    ToImageData: TW3ImageData;
    function    ToBytes: JUint8Array;
    function    ToBuffer:TW3MemoryBuffer;
    function    ToStream:TStream;

    Procedure   Stroke;

    Constructor Create(const aContext:TW3CustomGraphicContext);
    Destructor  Destroy;Override;

  TPixelFormat =(pf32Bit);

  TBitmap = Class(TObject)
    FCanvas:    TCanvas;
    FContext:   TW3GraphicContext;
    FWidth:     Integer;
    FHeight:    Integer;
    FOnLost:    TNotifyEvent;
    FOnGained:  TNotifyEvent;
    function    getWidth:Integer;
    procedure   setWidth(Value:Integer);
    function    getHeight:Integer;
    procedure   setHeight(Value:Integer);
    Procedure   ReCreateBitmap;
    function    getDC:JCanvasRenderingContext2D;
    Property    Empty:Boolean read (FCanvas<>NIL);
    Property    DC:JCanvasRenderingContext2D read getDC;
    Property    Canvas:TCanvas read FCanvas;
    Procedure   Allocate(aWidth,aHeight:Integer);
    Procedure   Release;
    Constructor Create;virtual;
    Destructor  Destroy;Override;
    Property    PixelFormat:TPixelFormat;
    Property    Width:Integer read getWidth write setWidth;
    property    Height:Integer read getHeight write setHeight;
    Property    OnBitmapAllocated:TNotifyEvent read FOnGained write FOnGained;
    Property    OnBitmapReleased:TNotifyEvent read FOnLost write FOnLost;