Difference between revisions of "User:CL"

From Apache OpenOffice Wiki
Jump to: navigation, search
(added Mac OS X category)
Line 93: Line 93:
 
[[Category:Development]]
 
[[Category:Development]]
 
[[Category:Aqua]]
 
[[Category:Aqua]]
 +
[[Category:MacOSX]]

Revision as of 10:09, 19 August 2006

My log of the vcl bitmap and widget stuff to the QUARTZ API

Nick on irc.freenode.net : ChristianL

Mail : mac AT fishbyte.de

DISCLAIMER

This is my personal wiki. Everything I write here
may be wrong, stupid, incorrect, harmful or worse.
The views expressed on this page aren't (necessarily)
the views of Sun Microsystems Inc. 

Status updates

2006-08-18

Screenshot of the day

Status: I optimized the AquaSalBitmap implementation. In my first emplementation I always created a CGBitmapContext with either 16 or 32 bit. This made it fast and easy to create CGImage for rendering. The cost was that for AquaSalBitmap::AquireBuffer I had to convert the mac format back to VCL for 1,4,8 and 24 bit formats. This also is a drawback because many SalBitmaps are not even used for drawing. For example when loading a bitmap from a file a SalBitmap with the original file format is created. Then this is copied via the Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics ) to have the same format as the current display. Also alpha masks are never drawn directly.

As a consequence, I now always store the bitmap data in a memory puffer in the format that is requested by VCL. Only if the bitmap is to be drawn on screen I create a CGBitmapContext and only convert the format if needed.

The biggest issue at the moment besides not having any raster operations is the problem with

  • AquaSalGraphics::getBitmap
  • AquaSalGraphics::copyBits
  • AquaSalGraphics::copyArea

This methods need access to the pixels on screen. This currently is used sometimes for transparency in bitmaps and also for late 80's style scrolling speedups. Getting pixels from an on screen window on the mac would require to directly access the buffer inside the graphic card.

Pavel send me this marvelous link how to get a pointer to the pixels inside the graphic card. I got that working but what I get was this.

The problem is that the mac does a gamma correctur. So what you see is what you get but not what you want. The image above shows a 32x32 area at the bottom right that is a copy of the same area at the top left. You can see that it is much brighter. Thats because on second paint it again is gamma corrected. Therefore the pixel information from the graphic card is not usable, unless we undo the gamma correction. But that slows a slow method down even more and also we lose precision.

So I rethink about my first aproach to this problem where I did all rendering to an offscreen CGBitmapContext and then blitting that to the window. This worked like a charm since you can access the unaltered pixel from a CGBitmapContext in contrast to a CGContext from a window.

There is a problem with this aproach. If we want to let the mac render native widgets we can either use the draw methods of the controls itself or the appereance manager. But both only render directly in a window. Therefore the pixels of the controls would not be present in the offscreen CGBitmapContext and could be overridden if we blit that part of the offscreen bitmap to the window.

My current idea is a mixed solution where we have a CGBitmapContext for each window and render twice. Once in the window directly and once in the offscreen bitmap. The offscreen bitmap is then only used to read pixels. This will be a significant overhead but on the other hand we will need an offscreen bitmap sooner or later to implement raster operations.

Open Issues

  • implement raster operations
  • make transparency bitmaps work
  • implement Invert methods
  • implement GetPixel method

Todo

  • Write something about raster operations

Code fragments

The following code creates a AquaSalBitmap from the window area (nX,nY,nDX,nDY). Problem is that the resulting pixels are already gamma corrected. Painting them again causes a second gamma correction.

CGrafPtr windowPort( GetWindowPort(mrWindow) );
LockPortBits(windowPort);

PixMapHandle thePixels( GetPortPixMap(windowPort) );
LockPixels(thePixels );

Rect windowBounds; 
GetWindowPortBounds ( mrWindow, &windowBounds);

Rect structureWidths;
// Obtains the width of the structure region on each edge of a window.
GetWindowStructureWidths ( mrWindow, &structureWidths );

// exclude left and top window border
nX += structureWidths.left;
nY += structureWidths.top;

AquaSalBitmap* pBitmap = new AquaSalBitmap;
ipBitmap->Create( windowBounds.right - windowBounds.left,
                  windowBounds.bottom - windowBounds.top,
                  GetBitCount(), GetPixRowBytes(thePixels),
                  reinterpret_cast< sal_uInt8* >( GetPixBaseAddr(thePixels)),
		  nX, nY, nDX, nDY );

UnlockPixels (thePixels);
UnlockPortBits(windowPort);	
Personal tools