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 » Strange issue with text in Painter
Re: Strange issue with text in Painter [message #50941 is a reply to message #50940] Mon, 14 January 2019 18:31 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
mirek wrote on Mon, 14 January 2019 18:45
Tom1 wrote on Mon, 14 January 2019 17:21
One potential reason for finding this issue is that I had just recently reached a point in my own code where I started to rotate the texts according to the original scale and rotation, both of which change constantly over the projection surface for maps where a change from one map projection to another has been carried out.

In effect this has caused an overwhelming increase in cached fonts here in my application.


Rotated texts in Painter are rotated by Painter matrix, they are cached in zero angle position...

Anyway, good info, I will think about this all...

Mirek


Well, yes, they are indeed cached in zero angle position. I should have expressed myself more clearly to make the point: Both fine scaling and fine rotation changes ultimately have an effect on double tolerance value solved using the Painter matrix scale and stored as caching key. This is also why rotating the image sometimes corrected the problem. Please see my early screenshots in this thread. (The changes would have been just at a magnitude of rounding errors i.e. just some LSBs.)

BR, Tom

[Updated on: Mon, 14 January 2019 18:37]

Report message to a moderator

Re: Strange issue with text in Painter [message #50942 is a reply to message #50941] Mon, 14 January 2019 18:39 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Tom1 wrote on Mon, 14 January 2019 18:31
mirek wrote on Mon, 14 January 2019 18:45
Tom1 wrote on Mon, 14 January 2019 17:21
One potential reason for finding this issue is that I had just recently reached a point in my own code where I started to rotate the texts according to the original scale and rotation, both of which change constantly over the projection surface for maps where a change from one map projection to another has been carried out.

In effect this has caused an overwhelming increase in cached fonts here in my application.


Rotated texts in Painter are rotated by Painter matrix, they are cached in zero angle position...

Anyway, good info, I will think about this all...

Mirek


Well, yes, they are indeed cached in zero angle position. I should have expressed myself more clearly to make the point: Both fine scaling and fine rotation changes ultimately have an effect on double tolerance value solved using the Painter matrix scale and stored as caching key. This is also why rotating the image sometimes corrected the problem. Please see my early screenshots in this thread. (The changes would have been just at a magnitude of rounding errors i.e. just some LSBs.)

BR, Tom


Well, yes, thats something I have missed so far. This is true and actually something to fix (probably round tolerance to like 10%).
Re: Strange issue with text in Painter [message #50944 is a reply to message #50942] Mon, 14 January 2019 19:53 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
EDIT: Perhaps check the possible fix first - the last post "OK, now I see possible bug, hard to say it is related, but please test:" and do testing only if it fails.

To test:

void BufferPainter::FinishPathJob()
{
	if(jobcount == 0)
		return;
/*	CoWork co;
	co * [&] {
		for(;;) {
			int i = co.Next();
			if(i >= jobcount)
				break;
			CoJob& b = cojob[i];
			b.rasterizer.Reset();
			PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, b.regular);
			if(!j.preclipped) {
				b.evenodd = j.evenodd;
				BufferPainter::RenderPathSegments(j.g, b.path_info->path[b.subpath], j.regular ? &b.attr : NULL, j.tolerance);
			}
		}
	};*/
	for(int i = 0; i < jobcount; i++) {
		CoJob& b = cojob[i];
		b.rasterizer.Reset();
		PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, b.regular);
		if(!j.preclipped) {
			b.evenodd = j.evenodd;
			BufferPainter::RenderPathSegments(j.g, b.path_info->path[b.subpath], j.regular ? &b.attr : NULL, j.tolerance);
		}
	}

	FinishFillJob();
	
	fillcount = jobcount;
	Swap(cofill, cojob); // Swap to keep allocated rasters (instead of pick)


(Changing the path rendering to run in ST)

[Updated on: Mon, 14 January 2019 22:57]

Report message to a moderator

Re: Strange issue with text in Painter [message #50945 is a reply to message #50944] Mon, 14 January 2019 20:51 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Worth testing how much tolerance has to do with it:

BufferPainter::PathJob::PathJob(Rasterizer& rasterizer, double width, const PathInfo *path_info,
                                const SimpleAttr& attr, const Rectf& preclip, bool isregular)
:	trans(attr.mtx)
{
	evenodd = attr.evenodd;
	regular = isregular && width < 0 && !path_info->ischar;

	g = &rasterizer;

	if(!IsNull(preclip.left) && !path_info->ischar) {
		double ex = max(width, 0.0) * (1 + attr.miter_limit);
		if(path_info->path_max.y + ex < preclip.top || path_info->path_min.y - ex > preclip.bottom ||
		   path_info->path_max.x + ex < preclip.left || path_info->path_min.x - ex > preclip.right) {
			preclipped = true;
			return;
		}
	}

	preclipped = false;

	if(regular)
		tolerance = 0.3;
	else {
		trans.target = g;
		g = &trans;
		tolerance = 0.3 / attr.mtx.GetScale();
	}

        tolerance = 0.3; // add this...
Re: Strange issue with text in Painter [message #50946 is a reply to message #50945] Mon, 14 January 2019 20:56 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
OK, now I see possible bug, hard to say it is related, but please test:

void BufferPainter::FinishPathJob()
{
	if(jobcount == 0)
		return;
	{
		CoWork co;
		co * [&] {
			for(;;) {
				int i = co.Next();
				if(i >= jobcount)
					break;
				CoJob& b = cojob[i];
				b.rasterizer.Reset();
				PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, b.regular);
				if(!j.preclipped) {
					b.evenodd = j.evenodd;
					BufferPainter::RenderPathSegments(j.g, b.path_info->path[b.subpath], j.regular ? &b.attr : NULL, j.tolerance);
				}
			}
		};
	}

	FinishFillJob();


(The difference is that CoWork is now inside block).
Re: Strange issue with text in Painter [message #50950 is a reply to message #50946] Tue, 15 January 2019 08:42 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
mirek wrote on Mon, 14 January 2019 21:56
OK, now I see possible bug, hard to say it is related, but please test:

void BufferPainter::FinishPathJob()
{
	if(jobcount == 0)
		return;
	{
		CoWork co;
		co * [&] {
			for(;;) {
				int i = co.Next();
				if(i >= jobcount)
					break;
				CoJob& b = cojob[i];
				b.rasterizer.Reset();
				PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, b.regular);
				if(!j.preclipped) {
					b.evenodd = j.evenodd;
					BufferPainter::RenderPathSegments(j.g, b.path_info->path[b.subpath], j.regular ? &b.attr : NULL, j.tolerance);
				}
			}
		};
	}

	FinishFillJob();


(The difference is that CoWork is now inside block).


Good morning,

This does not help. The problem is still there.

BR, Tom
Re: Strange issue with text in Painter [message #50951 is a reply to message #50944] Tue, 15 January 2019 08:53 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
mirek wrote on Mon, 14 January 2019 20:53
EDIT: Perhaps check the possible fix first - the last post "OK, now I see possible bug, hard to say it is related, but please test:" and do testing only if it fails.

To test:

void BufferPainter::FinishPathJob()
{
	if(jobcount == 0)
		return;
/*	CoWork co;
	co * [&] {
		for(;;) {
			int i = co.Next();
			if(i >= jobcount)
				break;
			CoJob& b = cojob[i];
			b.rasterizer.Reset();
			PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, b.regular);
			if(!j.preclipped) {
				b.evenodd = j.evenodd;
				BufferPainter::RenderPathSegments(j.g, b.path_info->path[b.subpath], j.regular ? &b.attr : NULL, j.tolerance);
			}
		}
	};*/
	for(int i = 0; i < jobcount; i++) {
		CoJob& b = cojob[i];
		b.rasterizer.Reset();
		PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, b.regular);
		if(!j.preclipped) {
			b.evenodd = j.evenodd;
			BufferPainter::RenderPathSegments(j.g, b.path_info->path[b.subpath], j.regular ? &b.attr : NULL, j.tolerance);
		}
	}

	FinishFillJob();
	
	fillcount = jobcount;
	Swap(cofill, cojob); // Swap to keep allocated rasters (instead of pick)


(Changing the path rendering to run in ST)


This fixes the issue.

I do not know if this has anything to do with it, but I have noticed that I cannot pass reference variables as parameters to CoWork::Do() -called functions. Compiler does not complain, but the code simply does not work correctly. I have had to switch to using pointers as parameters instead of reference variables in such functions.

BR, Tom
Re: Strange issue with text in Painter [message #50953 is a reply to message #50945] Tue, 15 January 2019 09:11 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
Hi,

As for forcing "tolerance = 0.3;" likely decreases the number of cache entries to a fraction of the original in this case, the likelihood to see any issues drops equally. And so it seems: I cannot see a single erroneous character.

Then again, I can check about 1000 names in a reasonable time on screen and if the problem is there, I will see just a few errors. I think that it becomes just a few errors in a million now, so I'm not 'lucky enough' to find them.

BR, Tom
Re: Strange issue with text in Painter [message #50954 is a reply to message #50951] Tue, 15 January 2019 09:15 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Tom1 wrote on Tue, 15 January 2019 08:53

I do not know if this has anything to do with it, but I have noticed that I cannot pass reference variables as parameters to CoWork::Do() -called functions. Compiler does not complain, but the code simply does not work correctly. I have had to switch to using pointers as parameters instead of reference variables in such functions.


That should not be issue here. Now all depends on details, but you always have to be careful that referenced variable exists until CoWork Finish or destructor... If you think that you have non-working example of different nature, please start a new thread a post it...

Mirek
Re: Strange issue with text in Painter [message #50955 is a reply to message #50953] Tue, 15 January 2019 09:17 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Tom1 wrote on Tue, 15 January 2019 09:11
Hi,

As for forcing "tolerance = 0.3;" likely decreases the number of cache entries to a fraction of the original in this case, the likelihood to see any issues drops equally. And so it seems: I cannot see a single erroneous character.

Then again, I can check about 1000 names in a reasonable time on screen and if the problem is there, I will see just a few errors. I think that it becomes just a few errors in a million now, so I'm not 'lucky enough' to find them.

BR, Tom


Understood, I mainly just wanted to know if the hypothesis is correct... (Revert the change, later I will introduce a nice simple fix to round tolerance, but we need to find the bug first).

Mirek
Re: Strange issue with text in Painter [message #50956 is a reply to message #50852] Tue, 15 January 2019 09:21 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
I am also trying to reproduce the issue here; anyway the paintings I have here only has a couple o texts in it.

Now I am not sure you have any level-of-detail systeme there, but if not, would it be possible to send me extremely zoomed out painting file so that it has more texts in it?

(That said, when testing, do you start with such zoomed-out situation?)
Re: Strange issue with text in Painter [message #50957 is a reply to message #50956] Tue, 15 January 2019 09:23 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
void BufferPainter::FinishPathJob()
{
	if(jobcount == 0)
		return;

	CoWork co;
	co * [&] {
		for(;;) {
			int i = co.Next();
			if(i >= jobcount)
				break;
			INTERLOCKED {
			CoJob& b = cojob[i];
			b.rasterizer.Reset();
			PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, b.regular);
			if(!j.preclipped) {
				b.evenodd = j.evenodd;
				BufferPainter::RenderPathSegments(j.g, b.path_info->path[b.subpath], j.regular ? &b.attr : NULL, j.tolerance);
			}
			}
		}
	};


If problem disappears, try to move INTERLOCKED down line by line (until if) to see when/if it reappears.
Re: Strange issue with text in Painter [message #50958 is a reply to message #50954] Tue, 15 January 2019 09:30 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
mirek wrote on Tue, 15 January 2019 10:15
Tom1 wrote on Tue, 15 January 2019 08:53

I do not know if this has anything to do with it, but I have noticed that I cannot pass reference variables as parameters to CoWork::Do() -called functions. Compiler does not complain, but the code simply does not work correctly. I have had to switch to using pointers as parameters instead of reference variables in such functions.


That should not be issue here. Now all depends on details, but you always have to be careful that referenced variable exists until CoWork Finish or destructor... If you think that you have non-working example of different nature, please start a new thread a post it...

Mirek


OK, will do when I have some time and can recall the accurate details of my problem with it to create a testcase.

BR, Tom
Re: Strange issue with text in Painter [message #50959 is a reply to message #50957] Tue, 15 January 2019 09:34 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
mirek wrote on Tue, 15 January 2019 10:23
void BufferPainter::FinishPathJob()
{
	if(jobcount == 0)
		return;

	CoWork co;
	co * [&] {
		for(;;) {
			int i = co.Next();
			if(i >= jobcount)
				break;
			INTERLOCKED {
			CoJob& b = cojob[i];
			b.rasterizer.Reset();
			PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, b.regular);
			if(!j.preclipped) {
				b.evenodd = j.evenodd;
				BufferPainter::RenderPathSegments(j.g, b.path_info->path[b.subpath], j.regular ? &b.attr : NULL, j.tolerance);
			}
			}
		}
	};


If problem disappears, try to move INTERLOCKED down line by line (until if) to see when/if it reappears.


This does not help.

BR, Tom
Re: Strange issue with text in Painter [message #50960 is a reply to message #50959] Tue, 15 January 2019 09:38 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
What about locking the whole lambda body?

Also to test in the same loop:

PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, false);

(change the last parameter to 'false')
Re: Strange issue with text in Painter [message #50961 is a reply to message #50956] Tue, 15 January 2019 09:42 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
mirek wrote on Tue, 15 January 2019 10:21
I am also trying to reproduce the issue here; anyway the paintings I have here only has a couple o texts in it.

Now I am not sure you have any level-of-detail systeme there, but if not, would it be possible to send me extremely zoomed out painting file so that it has more texts in it?

(That said, when testing, do you start with such zoomed-out situation?)


I do have a sort of level-of-detail system here, but I can squeeze quite a bunch of details on one UHD view still using smaller than readable fonts. You can then scale the painting to a readable level. Anyway, can you PM me your e-mail address, so that I can send you the painting. (It's still over 7MB when compressed with 7-zip at ultra level.)

BR, Tom
Re: Strange issue with text in Painter [message #50962 is a reply to message #50960] Tue, 15 January 2019 09:51 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
mirek wrote on Tue, 15 January 2019 10:38
What about locking the whole lambda body?

Also to test in the same loop:

PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, false);

(change the last parameter to 'false')


void BufferPainter::FinishPathJob()
{
	if(jobcount == 0)
		return;

	CoWork co;
	co * [&] {
		INTERLOCKED {
		for(;;) {
			int i = co.Next();
			if(i >= jobcount)
				break;
			CoJob& b = cojob[i];
			b.rasterizer.Reset();
			PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, b.regular);
			if(!j.preclipped) {
				b.evenodd = j.evenodd;
				BufferPainter::RenderPathSegments(j.g, b.path_info->path[b.subpath], j.regular ? &b.attr : NULL, j.tolerance);
			}
		}
		}
	};


This works OK. I will now test with 'false' instead of 'b.regular'.

BR, Tom
Re: Strange issue with text in Painter [message #50963 is a reply to message #50962] Tue, 15 January 2019 09:53 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
BTW, here is my testing code where I am trying to reproduce the issue:

#include <CtrlLib/CtrlLib.h>
#include <Painter/Painter.h>

using namespace Upp;

class PainterText : public TopWindow {
public:
	Painting p;
	FileSel fs;
	BufferPainter bpainter;
	double scale = 0.4;
	int    rotation = 0;
	Pointf translate = Pointf(0, 0);
	Pointf start;
	
	void Open(){
		if(fs.ExecuteOpen("Select a painting to view")) {
			p.Clear();
			p.Serialize(FileIn(fs.Get()));
		}
	}
	
	virtual void LeftDown(Point p, dword)
	{
		start = (Pointf)p * scale;
		SetCapture();
	}

	virtual void MouseMove(Point p, dword keyflags)
	{
		if(HasCapture()) {
			Pointf pos = (Pointf)p * scale;
			translate += (pos - start);
			start = pos;
			Refresh();
		}
	}

	virtual void MouseWheel(Point p, int zdelta, dword keyflags)
	{
		if(keyflags & K_CTRL)
			rotation += sgn(zdelta);
		else {
			if(zdelta < 0)
				scale *= 0.9;
			else
				scale /= 0.9;
		}
		Refresh();
	}


	virtual bool Key(dword key, int count){
		Refresh();
		switch(key){
			case K_CTRL_O:
				Open();
				return true;
		}
		return false;
	}
	
	typedef PainterText CLASSNAME;

	PainterText(){
		Sizeable();

		p.Serialize(FileIn("C:/xxx/PainteTest/T5.painting"));
	}
		
	virtual void Paint(Draw &draw){
		ImageBuffer ib(GetSize());
		{
			bpainter.Create(ib);
			bpainter.Co(true);
			bpainter.PreClipDashed();
			bpainter.Clear(White());
			bpainter.EvenOdd();
			
			bpainter.Scale(scale);
			bpainter.Rotate(rotation * .1);
			bpainter.Translate(translate);
			
			bpainter.Paint(p);

			bpainter.Finish();
		}
		
		SetSurface(draw,Rect(ib.GetSize()),ib,ib.GetSize(),Point(0,0));
	}
};

GUI_APP_MAIN
{
	PainterText().Run();
}


Perhaps you could try with the painting file you have produced - this is to ensure that I am doing the same thing...
Re: Strange issue with text in Painter [message #50964 is a reply to message #50960] Tue, 15 January 2019 09:53 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
mirek wrote on Tue, 15 January 2019 10:38
What about locking the whole lambda body?

Also to test in the same loop:

PathJob j(b.rasterizer, b.width, b.path_info, b.attr, b.preclip, false);

(change the last parameter to 'false')


Changing the last parameter to 'false' does not work.

BR, Tom
Re: Strange issue with text in Painter [message #50965 is a reply to message #50964] Tue, 15 January 2019 10:06 Go to previous messageGo to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
CharEntry fc_cache[512];

GlyphInfo GetGlyphInfo(Font font, int chr)
{
	INTERLOCKED {
		font.RealizeStd();
		unsigned hash = GlyphHash(font, chr);
		CharEntry& e = fc_cache[hash & 511];
		if(e.font != font.AsInt64() || e.chr != chr)
			e = GetGlyphEntry(font, chr, hash);
		return e.info;
	}
}

(removal of thread__ for fc_cache)

[Updated on: Tue, 15 January 2019 10:06]

Report message to a moderator

Previous Topic: MT + Subpixel appear incompatible in Painter
Next Topic: Painter: Excessive memory usage in PainterExamples moving window to edges of screen.
Goto Forum:
  


Current Time: Thu Mar 28 17:15:10 CET 2024

Total time taken to generate the page: 0.01507 seconds