Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » Draw, Display, Images, Bitmaps, Icons » Draw::DrawImageOp optimization bug
Re: Draw::DrawImageOp optimization bug [message #19411 is a reply to message #19410] Mon, 01 December 2008 14:52 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Tom1 wrote on Mon, 01 December 2008 08:37


To sum it up, the color space may indeed be different for raster and vector entities within the same device context. Not a very nice feature from the optimization point of view.



Indeed Sad

There are still "rat in the corner" means to overcome it.

The simple one comes to mind is to reuse small(er) uniform color Image to draw rectangles instead. E.g. something like 16x16 block.

Either tile it or stretch it.

Damn it. And I thought that the issue is solved, years ago Smile

Mirek
Re: Draw::DrawImageOp optimization bug [message #19416 is a reply to message #19411] Tue, 02 December 2008 19:15 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Update:

I have performed the first test on my brand new Epson SX100 - and the result is perfect, without any changes to the code Smile

Anyway, I plan to do this:

- print in printer resolution, increased to be <1000dpi (that should solve the "division lines" problem)

- only optimize out white areas (non-matching color problem)

I now think that I will add to Draw something like:

Pointf BeginNativeResolution();
void EndNativeResolution();

with Pointf containing constants to convert from dots to native pixels.

Mirek
Re: Draw::DrawImageOp optimization bug [message #19419 is a reply to message #19416] Tue, 02 December 2008 21:16 Go to previous messageGo to next message
Tom1
Messages: 659
Registered: March 2007
Contributor
Hi Mirek,

I'm not quite sure what you mean by "increased to be <1000dpi". Anyway, I think those changes will increase usability of both old printers and the yet to be published ones. I hope you make the pixels square (horizontal dpi = vertical dpi) even in the native resolution mode when the native pixels are not square. Otherwise, I suggest a flag for requesting square pixels in the call to BeginNativeResolution(bool useSquarePixelsFlag).

I will test it and report the results as soon as I get your solution from the SVN.

(Off the record: I did some testing today to print the RLE rectangles with StretchDIBits() and the results were pretty promising, but not quite perfect. 1x1 pixel source raster does not work correctly. It needs to be at least 1x2 for some reason. There were also still slight coverage problems with XPS when zoomed out -- although not nearly as bad as with rectangles.)

Thanks and regards,

Tom
Re: Draw::DrawImageOp optimization bug [message #19420 is a reply to message #19419] Tue, 02 December 2008 21:46 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Tom1 wrote on Tue, 02 December 2008 15:16

Hi Mirek,

I'm not quite sure what you mean by "increased to be <1000dpi". Anyway, I think those changes will increase usability of both old printers and the yet to be published ones. I hope you make the pixels square (horizontal dpi = vertical dpi) even in the native resolution mode when the native pixels are not square.



Uh, it would not be native mode then?!

Anyway, more information: For our "corpus delicti", Epson, the resolutions returned from GDI are either 360dpi or 720dpi (1440/5xxx is just marketing bluff).

Means I will simply go MM_TEXT mode as native.

Mirek
Re: Draw::DrawImageOp optimization bug [message #19429 is a reply to message #19420] Wed, 03 December 2008 12:14 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
luzr wrote on Tue, 02 December 2008 15:46

Tom1 wrote on Tue, 02 December 2008 15:16

Hi Mirek,

I'm not quite sure what you mean by "increased to be <1000dpi". Anyway, I think those changes will increase usability of both old printers and the yet to be published ones. I hope you make the pixels square (horizontal dpi = vertical dpi) even in the native resolution mode when the native pixels are not square.



Uh, it would not be native mode then?!

Anyway, more information: For our "corpus delicti", Epson, the resolutions returned from GDI are either 360dpi or 720dpi (1440/5xxx is just marketing bluff).

Means I will simply go MM_TEXT mode as native.

Mirek


OK, done. Seems OK so far (althought in fact, there is no visible difference on my Epson).

Mirek
Re: Draw::DrawImageOp optimization bug [message #19433 is a reply to message #19429] Wed, 03 December 2008 15:03 Go to previous messageGo to next message
Tom1
Messages: 659
Registered: March 2007
Contributor
Hi Mirek,

The printing seems to work now correctly for both XPS and also the older Epson printer where we had the scaling and other problems. Further on, the Xerox Phaser 6200 colors are even now within the image. Good work!

One thing popped up when reading the code. The BeginNative() call is followed by a conditional return without corresponding EndNative(). This may cause trouble in some cases. Maybe it should be written the other way around:

...
LTIMING("DrawImageOp");
if(IsNull(src))
	return;
BeginNative();
Native(x, y);
Native(cx, cy);
...


Thanks and best regards,

Tom
Re: Draw::DrawImageOp optimization bug [message #19434 is a reply to message #19433] Wed, 03 December 2008 15:21 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Tom1 wrote on Wed, 03 December 2008 09:03

Hi Mirek,

The printing seems to work now correctly for both XPS and also the older Epson printer where we had the scaling and other problems. Further on, the Xerox Phaser 6200 colors are even now within the image. Good work!

One thing popped up when reading the code. The BeginNative() call is followed by a conditional return without corresponding EndNative(). This may cause trouble in some cases. Maybe it should be written the other way around:

...
LTIMING("DrawImageOp");
if(IsNull(src))
	return;
BeginNative();
Native(x, y);
Native(cx, cy);
...


Thanks and best regards,

Tom



Thanks!

Mirek
Re: Draw::DrawImageOp optimization bug [message #19435 is a reply to message #19434] Wed, 03 December 2008 15:36 Go to previous messageGo to next message
Tom1
Messages: 659
Registered: March 2007
Contributor
Mirek,

One more thing: GetPagePixels returns the size as 600 dpi dots now even in the native mode. It would be very helpful if it returned the pixels according to the current addressing mode, i.e. native or dots mode.

Update: Also, would it be possible to return the currently effective DPI by the GetPixelsPerInch() in the same way? This would simplify using the same code for both printing and screen view.

Update 2: The code required for these:

Draw.h, Add/Change:
Size   pageDots;

Size  GetPagePixels() const { return native?pagePixels:pageDots; }
Size  GetPixelsPerInch() const { return native?nativeDpi:inchPixels; }


DrawWin32.cpp, Change:

void Draw::LoadCaps() {
...
pageDots = pagePixels = GetSizeCaps(HORZRES, VERTRES);
...
}

...

void PrintDraw::InitPrinter()
{
...
pageDots.cx = 600 * pagePixels.cx / nativeDpi.cx; 
pageDots.cy = 600 * pagePixels.cy / nativeDpi.cy; 
...
}


// Tom

[Updated on: Wed, 03 December 2008 17:28]

Report message to a moderator

Re: Draw::DrawImageOp optimization bug [message #19436 is a reply to message #19435] Wed, 03 December 2008 17:11 Go to previous messageGo to next message
Tom1
Messages: 659
Registered: March 2007
Contributor
Hi,

I ran some more tests on the native mode and discovered that the following should be changed in order to get correct scaling for the images in the native mode too:

1. There should not be switching to native mode and back in the Draw.cpp/Draw::DrawImageOp(). Also, there should not be any Native() translations for the coordinates.

2. The same goes probably for the DrawData.cpp/Draw::DrawDataOp(). No switching to native and back, and no coordinate translations.

Please remove:

BeginNative();
Native(x, y);
Native(cx, cy);
..
EndNative();

from both of the above functions.

The printing works correctly without these switchings in both native and dots mode. (By selecting the native mode, the user indicates that they wish to use the native coordinate space for all coordinates and create the content with that fact in mind.)

Best regards,

Tom
Re: Draw::DrawImageOp optimization bug [message #19442 is a reply to message #19435] Thu, 04 December 2008 10:19 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Tom1 wrote on Wed, 03 December 2008 09:36

Mirek,

One more thing: GetPagePixels returns the size as 600 dpi dots now even in the native mode. It would be very helpful if it returned the pixels according to the current addressing mode, i.e. native or dots mode.

Update: Also, would it be possible to return the currently effective DPI by the GetPixelsPerInch() in the same way? This would simplify using the same code for both printing and screen view.



Well, at the time, it was intentional design. You have GetNativeDpi there.

I have to think whether the proposed change is desirable.

Mirek
Re: Draw::DrawImageOp optimization bug [message #19443 is a reply to message #19436] Thu, 04 December 2008 10:22 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Tom1 wrote on Wed, 03 December 2008 11:11

Hi,

I ran some more tests on the native mode and discovered that the following should be changed in order to get correct scaling for the images in the native mode too:

1. There should not be switching to native mode and back in the Draw.cpp/Draw::DrawImageOp(). Also, there should not be any Native() translations for the coordinates.

2. The same goes probably for the DrawData.cpp/Draw::DrawDataOp(). No switching to native and back, and no coordinate translations.



Uh oh. DrawImage was the reason we have started all this stuff anyway.

Why do you suggest to throw all of that now?

Note that it is at least supposed to fix those line artifacts problem in the first place.

Mirek
Re: Draw::DrawImageOp optimization bug [message #19444 is a reply to message #19443] Thu, 04 December 2008 11:07 Go to previous messageGo to next message
Tom1
Messages: 659
Registered: March 2007
Contributor
Quote:


Uh oh. DrawImage was the reason we have started all this stuff anyway.

Why do you suggest to throw all of that now?

Note that it is at least supposed to fix those line artifacts problem in the first place.



I do not wish to throw away the BeginNative/EndNative/Native functions. Definitely not. They are really the key to use the native resolution in printing. That's great and they should stay there.

The problem is that DrawImageOp and DrawDataOp use the BeginNative/EndNative pair and the Native translations as if the coordinates input would be dots in all cases. This makes the coordinate space different for vector objects and the image objects.

Based on your code, I assume, you wanted to put the image to the printer on the native resolution. What happened was that if native mode was already on, the Native() calls did a second re-mapping of coordinates causing error in position and scale.

Basically switching the mode and the Native() calls would have been OK, if a check of the native recursion level was done and the Native() calls were conditional (if(native==1)) after switching. Anyway, the correct mapping of pixels to coordinate space was already achieved with the change that skipped ::SetDIBitsToDevice() call and used some other 'bitmap thing'. So I concluded that those calls are not needed in DrawImageOp and DrawDataOp at all. I removed the calls from there, tested it and it worked. Both in native and in dots mode.

Now, if you do these changes I suggest, I guess the situation will be that we should have a Draw:: for printing that by default is mapped with 600 dpi points and works OK with all printers we have tested so far. Additionally, if BeginNative is called, it will completely switch to printers native dpi mode and provides a consistent printing area at the printers native resolution instead of the 600 dpi.

The changes to GetPagePixels and GetPixelsPerInch support this. They will provide the correct values for the drawing area also after switching to native mode. Those changes will not break dots mode in any way.

Regards,

Tom
Re: Draw::DrawImageOp optimization bug [message #19445 is a reply to message #19444] Thu, 04 December 2008 11:36 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Yes, thinking about the issue, I have came to the same conclusion.

The key is to do Native conversion only if BeginNative was called for the first time.

Interesting question is whether we should add such logic directly into "Native" conversion methods.

Something like:

return native == 1 && inchPixels != nativeDpi ? iscale(x, nativeDpi.cx, 600) : x;

What do you think? Maybe it is a little bit too 'automatic', but I do not really see any flaws (yet Smile

The logic of Native methods then could be described as "what was your value before BeginNative now gets converted to the value you need inside BeginNative-EndNative block".

Mirek

[Updated on: Thu, 04 December 2008 11:39]

Report message to a moderator

Re: Draw::DrawImageOp optimization bug [message #19446 is a reply to message #19445] Thu, 04 December 2008 12:09 Go to previous messageGo to next message
Tom1
Messages: 659
Registered: March 2007
Contributor
I think I would not automate it. It will just require more thinking when expanding/debugging the code later -- especially if there are multiple levels of calls involved.

I think for a user of Draw::, there is no need to call the Native() functions at all. They will most probably either use dots by default and not care about any native stuff OR they will call BeginNative() once in the beginning of the page and then use that coordinate system for all of the page content. The Native() calls will probably be left for the uses inside the Draw:: itself. (Unless, of course, someone is doing something quite extraordinary that I can't imagine right now.) I think we should assume the user of Draw:: to know which mode he selected previously and behave accordingly.

// Tom
Re: Draw::DrawImageOp optimization bug [message #19449 is a reply to message #19446] Thu, 04 December 2008 12:36 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Tom1 wrote on Thu, 04 December 2008 06:09

I think I would not automate it. It will just require more thinking when expanding/debugging the code later -- especially if there are multiple levels of calls involved.

I think for a user of Draw::, there is no need to call the Native() functions at all. They will most probably either use dots by default and not care about any native stuff OR they will call BeginNative() once in the beginning of the page and then use that coordinate system for all of the page content. The Native() calls will probably be left for the uses inside the Draw:: itself. (Unless, of course, someone is doing something quite extraordinary that I can't imagine right now.) I think we should assume the user of Draw:: to know which mode he selected previously and behave accordingly.

// Tom



Well, that would mean test in DrawImage / DrawData, right?

Mirek
Re: Draw::DrawImageOp optimization bug [message #19450 is a reply to message #19449] Thu, 04 December 2008 13:09 Go to previous messageGo to next message
Tom1
Messages: 659
Registered: March 2007
Contributor
Yes, this would mean the 'if(native==1)' testing in DrawImage / DrawData.

I must emphasize that switching to native in DrawImage/DrawData is not required at all unless you wish to put back the SetSurface (::SetDIBitsToDevice) based image printing to Image::Data::Paint().

// Tom
Re: Draw::DrawImageOp optimization bug [message #19453 is a reply to message #19450] Thu, 04 December 2008 15:53 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Tom1 wrote on Thu, 04 December 2008 07:09

Yes, this would mean the 'if(native==1)' testing in DrawImage / DrawData.

I must emphasize that switching to native in DrawImage/DrawData is not required at all unless you wish to put back the SetSurface (::SetDIBitsToDevice) based image printing to Image::Data::Paint().

// Tom


I believe we still might need it to overcome horizontal line artifacts.

And the quality should be now better, as Image is rescaled just once, directly to printer resolution.

Anyway, DrawImage/Data fixed.

Mirek
Re: Draw::DrawImageOp optimization bug [message #19455 is a reply to message #19453] Thu, 04 December 2008 16:07 Go to previous messageGo to next message
Tom1
Messages: 659
Registered: March 2007
Contributor
luzr wrote on Thu, 04 December 2008 16:53


I believe we still might need it to overcome horizontal line artifacts.
And the quality should be now better, as Image is rescaled just once, directly to printer resolution.

Anyway, DrawImage/Data fixed.

Mirek



Doing image rescaling just once in dots mode is a very good reason indeed for your approach, I agree.

What about GetPagePixels and GetPixelsPerInch updates? Can you throw them in? I assume nobody currently using them would expect to get different values from them than what the currently active coordinate space uses.

Thanks,

Tom
Re: Draw::DrawImageOp optimization bug [message #19456 is a reply to message #19455] Thu, 04 December 2008 17:46 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Done.

I hope our little printing crysis is thus over Smile

Mirek
Re: Draw::DrawImageOp optimization bug [message #19470 is a reply to message #19456] Fri, 05 December 2008 11:05 Go to previous messageGo to previous message
Tom1
Messages: 659
Registered: March 2007
Contributor
Mirek,

Thank you for the latest fixes. I have tested with all my real printers with success using both dots and native mode. Now, I will also involve my client with the Epson printer to verify the results on that particular hardware. I would not expect any trouble on that, as the preview is OK.

With Microsoft XPS Document Writer + Viewer, there is still horizontal lines if the image gets even partly optimized. Over-painting the image segments does not help. (This can be seen if the Testcase image (O) is drawn with red on white instead of red on blue.) I assume this happens because the XPS Viewer smooths the image and the intensity at the edge of each colored image segment is lower than the pixel color due to smoothing. Therefore, each new stripe paints a narrow line with lighter color.

I suppose, the RLE optimization of images is just impossible with XPS but luckily appears to work well for real printers after the 'optimize-white-only' -change. I guess, there is just the 'disable RLE optimization' -flag left as an option to survive printing to XPS.

Overall, the changes have improved the printing sub-system compatibility and printing quality. Especially the native mode has been an extremely welcome feature.

Thanks and regards,

Tom
Previous Topic: Extensions to Draw...Ops
Next Topic: Compile package with iml file problem!
Goto Forum:
  


Current Time: Wed Nov 20 19:04:21 CET 2019

Total time taken to generate the page: 0.01249 seconds