U++ framework
Do not panic. Ask here before giving up.

Home » U++ Library support » Draw, Display, Images, Bitmaps, Icons » Strange issue with text in Painter
Strange issue with text in Painter [message #50852] Wed, 09 January 2019 11:23 Go to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi,

Here's a strange issue: When I render a map using Painter, sometimes some letter does not render at all at specific scales. Alternatively, as you can see in the attached picture, it may render at false scale:

index.php?t=getfile&id=5733&private=0

When rotating the map slightly, the same text renders correctly:

index.php?t=getfile&id=5734&private=0

...Unless when the rotation is exactly 90, 180 or 270 degrees, which causes similar scaling error.

Another variant is that the letter appears to be completely absent.

BUT: when zooming the map, the letter renders perfectly OK.

There is no difference if Painter is in MT or ST mode.

Finally, this behavior persists for that run of the program only. If I close and restart the program, the same letter will likely render OK all the time, but there may (or may not) be another letter that suffers from the same problem.

I think this is some sort of initialization problem with fonts... but who knows.

Best regards,

Tom
  • Attachment: T1.png
    (Size: 203.15KB, Downloaded 1091 times)
  • Attachment: T2.png
    (Size: 138.87KB, Downloaded 1120 times)
Re: Strange issue with text in Painter [message #50854 is a reply to message #50852] Wed, 09 January 2019 13:38 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi,

Here's some more. In this picture two of the letters have shrinked in the middle of a word:

index.php?t=getfile&id=5736&private=0

When zooming in, the text gets fixed:

index.php?t=getfile&id=5735&private=0

Instead of a testcase, here's a clip of the code I use for rendering the text with Painter:

			Font fnt(font);
			fnt.Height((int)floor(height_dp)).Bold(object.bold).Italic(object.italic==1).Underline(object.selected);
			
			Pointf p(project.Transform(object.x,object.y));
			double  rot=object.rotation+rotation;
			rot+=object.no_rotate?-GetViewRotation():0;

			painter.Begin();

			painter.Translate(p);
			if(rot) painter.Rotate(-rot*DEGR2RAD);
			switch(object.italic){
				case 2:
					painter.Transform(Xform2D::Sheer(-0.3));
					break;
				case 3:
					painter.Transform(Xform2D::Sheer(0.2));
					break;
			}
			
			Vector<String> lines=Split(text,10);
			
			for(int row=0;row<lines.GetCount();row++){
				Size sz=GetTextSize(lines[row],fnt);
				Pointf delta(0,0);
				switch(object.attpoint){
					case 1:	// 1 = Top left
						break;
					case 2: // Top Center
						delta.x=-sz.cx/2;
						break;
					case 3: // Top Right
						delta.x=-sz.cx;
						break;
					case 4: // Middle Left
						delta.y=-sz.cy/2;
						break;
					case 5: // Middle Center
						delta.y=-sz.cy/2;
						delta.x=-sz.cx/2;
						break;
					case 6: // Middle Right
						delta.y=-sz.cy/2;
						delta.x=-sz.cx;
						break;
					default:
					case 7: // Bottom Left
						delta.y=-sz.cy;
						break;
					case 8: // Bottom Center
						delta.y=-sz.cy;
						delta.x=-sz.cx/2;
						break;
					case 9: // Bottom Right
						delta.y=-sz.cy;
						delta.x=-sz.cx;
						break;
				}
				delta.y+=row*height_dp*1.5; // sz.cy
				painter.Text(delta,lines[row],fnt);
			}
			
			if(edgecolor.a) painter.Stroke(height_dp*0.1,edgecolor);
			painter.Fill(textcolor);
			painter.End();


Best regards,

Tom
  • Attachment: T4.png
    (Size: 80.69KB, Downloaded 1038 times)
  • Attachment: T3.png
    (Size: 82.44KB, Downloaded 1039 times)
Re: Strange issue with text in Painter [message #50859 is a reply to message #50854] Thu, 10 January 2019 17:09 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
I can see nothing obvious, but it feels like caching issue.

Please try this:

void ApproximateChar(LinearPathConsumer& t, Pointf at, int ch, Font fnt, double tolerance)
{
	PAINTER_TIMING("ApproximateChar");
	Value v;
	INTERLOCKED {
		PAINTER_TIMING("ApproximateChar::Fetch");
		static LRUCache<Value, GlyphKey> cache;
		cache.Shrink(500000);
		sMakeGlyph h;
		h.gk.fnt = fnt;
		h.gk.chr = ch;
		h.gk.tolerance = tolerance;
		v = cache.Get(h);
	}
#if 1
	GlyphPainter chp;
	chp.move = chp.pos = Null;
	chp.tolerance = tolerance;
	PaintCharacter(chp, Pointf(0, 0), ch, fnt);
	Vector<float>& g = chp.glyph;
#else
	const Vector<float>& g = ValueTo< Vector<float> >(v);
#endif
	int i = 0;
	while(i < g.GetCount()) {
		Pointf p;
		p.x = g[i++];
		if(p.x > 1e30) {
			p.x = g[i++];
			p.y = g[i++];
			t.Move(p + at);
		}
		else {
			PAINTER_TIMING("ApproximateChar::Line");
			p.y = g[i++];
			t.Line(p + at);
		}
	}
}


(This switches caching off.)

Mirek
Re: Strange issue with text in Painter [message #50861 is a reply to message #50859] Thu, 10 January 2019 17:26 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi,

Thanks! I will check this too tomorrow!

Anyway, if this does not sort out easily, I can store the problematic sequence in a Painting and serialize it in a file for you to check out. (The same procedure as last time, when there was a complex Painter issue.)

Thanks,

Tom
Re: Strange issue with text in Painter [message #50862 is a reply to message #50861] Thu, 10 January 2019 17:46 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Tom1 wrote on Thu, 10 January 2019 17:26
Hi,

Thanks! I will check this too tomorrow!

Anyway, if this does not sort out easily, I can store the problematic sequence in a Painting and serialize it in a file for you to check out. (The same procedure as last time, when there was a complex Painter issue.)

Thanks,

Tom


Yes, good idea.

Also, if my code change does not solve the problem, try this:

void BufferPainter::CharacterOp(const Pointf& p, int ch, Font fnt)
{
	LLOG("@ CharacterOp " << p << ", " << ch << ", " << fnt);
#if 1
	DoMove0();
	PaintCharacter(*this, p, ch, fnt);
#else
	move = current = EndPoint(p, false);
	auto& m = PathAdd<CharData>(CHAR);
	m.p = EndPoint(p, false);
	m.ch = ch;
	m.fnt = fnt;
	path_info->ischar = true;
	EvenOdd();
#endif
}


(It is similar - removing caching - just on another level)
Re: Strange issue with text in Painter [message #50866 is a reply to message #50862] Fri, 11 January 2019 09:40 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi Mirek,

The change in ApproximateChar() appears to fix the issue. However, as can be expected, the rendering speed drops dramatically.

I will next revert the ApproximateChar() changes and then test the BufferPainter::CharacterOp() change...

Best regards,

Tom
Re: Strange issue with text in Painter [message #50867 is a reply to message #50866] Fri, 11 January 2019 10:07 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi,

Also the change in BufferPainter::CharacterOp() seems to fix the issue. Similarly, the rendering speed drops.

The special thing about these maps I'm rendering is that they have an extremely small change in the text rotation thorough out the map page as they have been transformed from one coordinate projection to another (Transverse Mercator to Mercator in this case) and this involves a change in text rotation by the amount of meridian convergence value. This boils down to just parts of a degree through out the entire map width. I do not know if the caching gets affected by this or not.

I also generated a serialized painting, but it did not exhibit the issue. I think this is because the history for the cache is different and therefore the problem does not show up.

Best regards,

Tom
Re: Strange issue with text in Painter [message #50868 is a reply to message #50867] Fri, 11 January 2019 10:10 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
So I am looking into caching right now.. One possibility is that this is caused by font replacements.

What is the Font use? If it is anything else than arial, does changing the font to Arial fix the issue?

Mirek
Re: Strange issue with text in Painter [message #50869 is a reply to message #50868] Fri, 11 January 2019 10:17 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
The font was "font=Font(Font::SANSSERIF,12);"

Changed to "font=Font(Font::ARIAL,12);", but nothing changes.

(I think the enum makes these two the same.)

BR,

Tom
Re: Strange issue with text in Painter [message #50870 is a reply to message #50869] Fri, 11 January 2019 11:05 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Could you add these DLOGs

struct GlyphKey {
	Font   fnt;
	int    chr;
	double tolerance;
	
	bool operator==(const GlyphKey& b) const {
		DLOG("*** operator==");
		DDUMP(fnt);
		DDUMP(b.fnt);
		DDUMP(chr);
		DDUMP(b.chr);
		return fnt == b.fnt && chr == b.chr && tolerance == b.tolerance;
	}
	unsigned GetHashValue() const {
		return CombineHash(fnt, chr, tolerance);
	}
};

struct sMakeGlyph : LRUCache<Value, GlyphKey>::Maker {
	GlyphKey gk;

	GlyphKey Key() const     { return gk; }
	int      Make(Value& v) const {
		GlyphPainter gp;
		gp.move = gp.pos = Null;
		gp.tolerance = gk.tolerance;
		DLOG("*** Make");
		DDUMP(GetHashValue(gk));
		DDUMP(gk.fnt);
		DDUMP(gk.chr);
		PaintCharacter(gp, Pointf(0, 0), gk.chr, gk.fnt);
		int sz = gp.glyph.GetCount() * 4;
		v = RawPickToValue(pick(gp.glyph));
		return sz;
	}
};

void ApproximateChar(LinearPathConsumer& t, Pointf at, int ch, Font fnt, double tolerance)
{
	PAINTER_TIMING("ApproximateChar");
	Value v;
	INTERLOCKED {
		DLOG("==== ApproximateChar " << ch << " " << fnt);
		PAINTER_TIMING("ApproximateChar::Fetch");
		static LRUCache<Value, GlyphKey> cache;
		cache.Shrink(500000);
		sMakeGlyph h;
		h.gk.fnt = fnt;
		h.gk.chr = ch;
		h.gk.tolerance = tolerance;
		DDUMP(GetHashValue(h.gk));
		v = cache.Get(h);
	}
#if 0
	GlyphPainter chp;
	chp.move = chp.pos = Null;
	chp.tolerance = tolerance;
	PaintCharacter(chp, Pointf(0, 0), ch, fnt);
	const Vector<float>& g = chp.glyph;
#else
	const Vector<float>& g = ValueTo< Vector<float> >(v);
#endif
	int i = 0;
	while(i < g.GetCount()) {
		Pointf p;
		p.x = g[i++];
		if(p.x > 1e30) {
			p.x = g[i++];
			p.y = g[i++];
			t.Move(p + at);
		}
		else {
			PAINTER_TIMING("ApproximateChar::Line");
			p.y = g[i++];
			t.Line(p + at);
		}
	}
}


then bring it into error state, send me the screenshot and .log?

Thanks,

Mirek

[Updated on: Fri, 11 January 2019 11:16]

Report message to a moderator

Re: Strange issue with text in Painter [message #50871 is a reply to message #50870] Fri, 11 January 2019 11:46 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi,

Here you go! Please find attached a the log, a screenshot and the serialized painting of the same.

As you can see in the painting, the text should read 'Perttilä', not ' erttilä'.

(You can view the painting using the PainterBench -tool.)

BR,

Tom

PS: The DLOG and DDUMP cause errors in RELEASE mode, but not in DEBUG mode though:
----- Painter ( GUI PROTECT MSC17X64 MSC WIN32 ) (8 / 32)
RenderChar.cpp
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(96): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(97): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(98): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(99): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(100): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(116): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(117): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(118): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(119): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(132): error C2018: unknown character '0x40'
C:\upp-12610\upp.src\uppsrc\Painter\RenderChar.cpp(140): error C2018: unknown character '0x40'
Painter: 1 file(s) built in (0:00.90), 902 msecs / file, duration = 910 msecs, parallelization 0%
  • Attachment: T5.7z
    (Size: 407.08KB, Downloaded 309 times)

[Updated on: Fri, 11 January 2019 11:52]

Report message to a moderator

Re: Strange issue with text in Painter [message #50872 is a reply to message #50871] Fri, 11 January 2019 12:10 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Tom1 wrote on Fri, 11 January 2019 11:46
Hi,
PS: The DLOG and DDUMP cause errors in RELEASE mode, but not in DEBUG mode though:


That is by design. It forces you to remove LOGs that you have inserted for debugging purposes. Not ideal, but better than to have logfile overcrowded with forgotten debugging info that you have needed 5 years ago Smile
Re: Strange issue with text in Painter [message #50873 is a reply to message #50872] Fri, 11 January 2019 12:12 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
mirek wrote on Fri, 11 January 2019 13:10
Tom1 wrote on Fri, 11 January 2019 11:46
Hi,
PS: The DLOG and DDUMP cause errors in RELEASE mode, but not in DEBUG mode though:


That is by design. It forces you to remove LOGs that you have inserted for debugging purposes. Not ideal, but better than to have logfile overcrowded with forgotten debugging info that you have needed 5 years ago Smile


Good point! Surprised
Re: Strange issue with text in Painter [message #50874 is a reply to message #50872] Fri, 11 January 2019 12:33 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
No luck... Let us add more logging:

struct GlyphKey {
	Font   fnt;
	int    chr;
	double tolerance;
	
	bool operator==(const GlyphKey& b) const {
		DLOG("*** operator==");
		DDUMP(fnt);
		DDUMP(b.fnt);
		DDUMP(chr);
		DDUMP(b.chr);
		return fnt == b.fnt && chr == b.chr && tolerance == b.tolerance;
	}
	unsigned GetHashValue() const {
		return CombineHash(fnt, chr, tolerance);
	}
};

struct sMakeGlyph : LRUCache<Value, GlyphKey>::Maker {
	GlyphKey gk;

	GlyphKey Key() const     { return gk; }
	int      Make(Value& v) const {
		GlyphPainter gp;
		gp.move = gp.pos = Null;
		gp.tolerance = gk.tolerance;
		DLOG("*** Make");
		DDUMP(GetHashValue(gk));
		DDUMP(gk.fnt);
		DDUMP(gk.chr);
		PaintCharacter(gp, Pointf(0, 0), gk.chr, gk.fnt);
		int sz = gp.glyph.GetCount() * 4;
		v = RawPickToValue(pick(gp.glyph));
		return sz;
	}
};

void ApproximateChar(LinearPathConsumer& t, Pointf at, int ch, Font fnt, double tolerance)
{
	PAINTER_TIMING("ApproximateChar");
	Value v;
	INTERLOCKED {
		DLOG("==== ApproximateChar " << ch << " " << fnt);
		PAINTER_TIMING("ApproximateChar::Fetch");
		static LRUCache<Value, GlyphKey> cache;
		cache.Shrink(500000);
		sMakeGlyph h;
		h.gk.fnt = fnt;
		h.gk.chr = ch;
		h.gk.tolerance = tolerance;
		DDUMP(GetHashValue(h.gk));
		v = cache.Get(h);
		DDUMP(ValueTo< Vector<float> >(v));
	}
#if 0
	GlyphPainter chp;
	chp.move = chp.pos = Null;
	chp.tolerance = tolerance;
	PaintCharacter(chp, Pointf(0, 0), ch, fnt);
	const Vector<float>& g = chp.glyph;
#else
	const Vector<float>& g = ValueTo< Vector<float> >(v);
#endif
	int i = 0;
	while(i < g.GetCount()) {
		Pointf p;
		p.x = g[i++];
		if(p.x > 1e30) {
			p.x = g[i++];
			p.y = g[i++];
			t.Move(p + at);
		}
		else {
			PAINTER_TIMING("ApproximateChar::Line");
			p.y = g[i++];
			t.Line(p + at);
		}
	}
}


the same (no need to send painting, just .log and tell me what letter is missing / wrong).

Thanks,

Mirek
Re: Strange issue with text in Painter [message #50875 is a reply to message #50874] Fri, 11 January 2019 12:53 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi,

Here's the new log. No images or paintings this time Smile

The failed letter was a capital 'U' this time (at false size).

Best regards,

Tom
  • Attachment: ChartTest.7z
    (Size: 31.57KB, Downloaded 341 times)
Re: Strange issue with text in Painter [message #50877 is a reply to message #50875] Fri, 11 January 2019 14:33 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi,

Here's one sequence (of log) where the first letter 'J' is rendered too large:

==== ApproximateChar 74 <Arial:27>
GetHashValue(h.gk) = 3041017192
*** operator==
fnt = <Arial:27>
b.fnt = <Arial:5 Italic>
chr = 74
b.chr = 214
*** operator==
fnt = <Arial:27>
b.fnt = <Arial:27>
chr = 74
b.chr = 74
ValueTo< Vector<float> >(v) = [9.99999984824321e30, 1, 17.46875, 4, 17, 4.39453125, 19.908203125, 5.296875, 21.7265625, 6.671875, 22.681640625, 8.484375, 23, 9.892578125, 22.84765625, 11.0859375, 22.390625, 12.00390625, 21.671875, 12.5859375, 20.734375, 13, 17.390625, 13, -1, 16, -1, 16, 17.09375, 15.79296875, 20.046875, 15.171875, 22.25, 14.1015625, 23.861328125, 12.546875, 25.0390625, 10.59375, 25.759765625, 8.328125, 26, 6.63671875, 25.86572265625, 5.15625, 25.462890625, 3.88671875, 24.79150390625, 2.828125, 23.8515625, 1.9990234375, 22.64697265625, 1.41796875, 21.181640625, 1, 17.46875]
==== ApproximateChar 111 <Arial:27>
GetHashValue(h.gk) = 3041016509
*** operator==
fnt = <Arial:27>
b.fnt = <Arial:27>
chr = 111
b.chr = 111
ValueTo< Vector<float> >(v) = [9.99999984824321e30, 1, 18.5, 1.1337890625, 16.63671875, 1.53515625, 15.03125, 2.2041015625, 13.68359375, 3.140625, 12.59375, 5.12890625, 11.3984375, 7.5, 11, 10.109375, 11.484375, 12.1875, 12.9375, 13.546875, 15.24609375, 14, 18.296875, 13.798828125, 20.76953125, 13.1953125, 22.65625, 12.208984375, 24.0703125, 10.859375, 25.125, 9.25390625, 25.78125, 7.5, 26, 4.87109375, 25.517578125, 2.796875, 24.0703125, 2.0107421875, 22.99853515625, 1.44921875, 21.712890625, 1, 18.5, 9.99999984824321e30, 3, 18.5, 3.3203125, 20.90625, 4.28125, 22.625, 5.7265625, 23.65625, 7.5, 24, 9.2734375, 23.654296875, 10.71875, 22.6171875, 11.6796875, 20.873046875, 12, 18.40625, 11.677734375, 16.0703125, 10.7109375, 14.375, 9.263671875, 13.34375, 7.5, 13, 5.7265625, 13.341796875, 4.28125, 14.3671875, 3.3203125, 16.083984375, 3, 18.5]
==== ApproximateChar 101 <Arial:27>
GetHashValue(h.gk) = 3041016535
*** operator==
fnt = <Arial:27>
b.fnt = <Arial:27>
chr = 101
b.chr = 101
ValueTo< Vector<float> >(v) = [9.99999984824321e30, 11.96875, 22, 13.9375, 22, 13.107421875, 23.69140625, 11.7734375, 24.953125, 9.970703125, 25.73828125, 7.734375, 26, 4.94921875, 25.515625, 2.8125, 24.0625, 1.453125, 21.734375, 1, 18.625, 1.458984375, 15.40625, 2.03271484375, 14.1015625, 2.8359375, 13, 4.943359375, 11.5, 7.59375, 11, 10.162109375, 11.482421875, 12.2109375, 12.9296875, 13.552734375, 15.251953125, 14, 18.359375, 13.984375, 19, 3, 19, 3.44921875, 21.138671875, 4.484375, 22.7109375, 5.9765625, 23.677734375, 7.796875, 24, 10.3125, 23.5234375, 11.25, 22.904296875, 11.96875, 22, 9.99999984824321e30, 3, 17, 12, 17, 11.6484375, 15.46484375, 10.96875, 14.359375, 9.46484375, 13.33984375, 7.578125, 13, 5.8515625, 13.271484375, 4.421875, 14.0859375, 3.42578125, 15.357421875, 3, 17]


Interestingly it always has two operator== hash compares until a match is found. (I repeated the rendering multiple times to find the spot in log more easily.) Is this multiple hash match affecting the caching in some way?

BR,

Tom

PS: When a wrong cache item is picked for a character, it may have wrong size and wrong Italic/Normal coding, but it always is the correct letter (if it is visible at all). I think the complete lack of visibility might come from very small size of the cached character. This is almost like the LRUCache only looked at the character code when picking the result. Well, of course this is not the case, since otherwise most of the text items would be trash I guess...

[Updated on: Fri, 11 January 2019 15:25]

Report message to a moderator

Re: Strange issue with text in Painter [message #50879 is a reply to message #50877] Fri, 11 January 2019 15:29 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Tom1 wrote on Fri, 11 January 2019 14:33
Hi,
Interestingly it always has two operator== hash compares until a match is found. (I repeated the rendering multiple times to find the spot in log more easily.) Is this multiple hash match affecting the caching in some way?


That is hashcode collision. Nothing to worry about.

Quote:

PS: When a wrong cache item is picked for a character, it may have wrong size and wrong Italic/Normal coding, but it always is the correct


Wrong italic/normal bit is new - is that sure?

Mirek
Re: Strange issue with text in Painter [message #50880 is a reply to message #50879] Fri, 11 January 2019 15:33 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi,

The first message in this thread portrays that: The 'Ă–rviksudden' should have been in italic, but was instead shown with straight up 'Ă–', if you look at it carefully. I have seen this in other tests too occasionally, so I can confirm it.

Best regards,

Tom
Re: Strange issue with text in Painter [message #50881 is a reply to message #50880] Fri, 11 January 2019 15:43 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Still no clues... Anyway, let us modify logging a bit:

void ApproximateChar(LinearPathConsumer& t, Pointf at, int ch, Font fnt, double tolerance)
{
	PAINTER_TIMING("ApproximateChar");
	Value v;
	INTERLOCKED {
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		PAINTER_TIMING("ApproximateChar::Fetch");
		static LRUCache<Value, GlyphKey> cache;
		cache.Shrink(500000);
		sMakeGlyph h;
		h.gk.fnt = fnt;
		h.gk.chr = ch;
		h.gk.tolerance = tolerance;
		v = cache.Get(h);
		DDUMP(ValueTo< Vector<float> >(v));
#if 1
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
		DDUMP(chp.glyph);
		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif
	}
	const Vector<float>& g = ValueTo< Vector<float> >(v);
	int i = 0;
	while(i < g.GetCount()) {
		Pointf p;
		p.x = g[i++];
		if(p.x > 1e30) {
			p.x = g[i++];
			p.y = g[i++];
			t.Move(p + at);
		}
		else {
			PAINTER_TIMING("ApproximateChar::Line");
			p.y = g[i++];
			t.Line(p + at);
		}
	}
}


(If error is here, it should also assert....)
Re: Strange issue with text in Painter [message #50882 is a reply to message #50880] Fri, 11 January 2019 15:47 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Tom1 wrote on Fri, 11 January 2019 15:33
Hi,

The first message in this thread portrays that: The 'Ă–rviksudden' should have been in italic, but was instead shown with straight up 'Ă–', if you look at it carefully. I have seen this in other tests too occasionally, so I can confirm it.



Well, alternative theory is that some letters are rendered with wrong transformation matrix... I guess random matrix would explain both wrong size and "unitalicizing".....

Anyway, it would probably also create some more profound artefacts that you have not observed yet (?)

Mirek
Re: Strange issue with text in Painter [message #50884 is a reply to message #50881] Fri, 11 January 2019 18:50 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
mirek wrote on Fri, 11 January 2019 16:43
Still no clues... Anyway, let us modify logging a bit:

void ApproximateChar(LinearPathConsumer& t, Pointf at, int ch, Font fnt, double tolerance)
{
	PAINTER_TIMING("ApproximateChar");
	Value v;
	INTERLOCKED {
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		PAINTER_TIMING("ApproximateChar::Fetch");
		static LRUCache<Value, GlyphKey> cache;
		cache.Shrink(500000);
		sMakeGlyph h;
		h.gk.fnt = fnt;
		h.gk.chr = ch;
		h.gk.tolerance = tolerance;
		v = cache.Get(h);
		DDUMP(ValueTo< Vector<float> >(v));
#if 1
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
		DDUMP(chp.glyph);
		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif
	}
	const Vector<float>& g = ValueTo< Vector<float> >(v);
	int i = 0;
	while(i < g.GetCount()) {
		Pointf p;
		p.x = g[i++];
		if(p.x > 1e30) {
			p.x = g[i++];
			p.y = g[i++];
			t.Move(p + at);
		}
		else {
			PAINTER_TIMING("ApproximateChar::Line");
			p.y = g[i++];
			t.Line(p + at);
		}
	}
}


(If error is here, it should also assert....)


Strangely enough, this did not exhibit the problem at all. There are no buggy letters, as far as I could tell from looking around the map for 30 minutes. No asserts either, but that is to be expected as the problem did not surface here... I have been running with MSBT17x64 but I must next look at 32-bit compiler to see if it behaves differently. And maybe test on Linux too to see if the behavior changes.

I will continue with this on Monday...

As for the transformation matrix, I cannot see a chance for it to change between successive letters. That would require another thread to break the matrix, but this issue happens in ST too, so I think it is next to impossible.

Anyway, thanks for your efforts on this so far and have a nice weekend!

Tom

Re: Strange issue with text in Painter [message #50885 is a reply to message #50882] Fri, 11 January 2019 19:26 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
IDK, I see no issues and as the last try I a have adapted our benchmarking snippet to test zooming in hope that it will reproduce the caching error:

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

using namespace Upp;

class PainterText : public TopWindow {
public:
	Painting p;
	FileSel fs;
	BufferPainter bpainter;
	double scale = 2;
	
	void Open(){
		if(fs.ExecuteOpen("Select a painting to view")){
			p.Clear();
			p.Serialize(FileIn(fs.Get()));
		}
	}

	virtual void MouseWheel(Point p, int zdelta, dword keyflags)
	{
		if(zdelta < 0)
			scale *= 0.8;
		else
			scale /= 0.8;
		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(false);
			bpainter.PreClipDashed();
			bpainter.Clear(White());
			bpainter.EvenOdd();
			
			bpainter.Scale(scale);
			bpainter.Paint(p);

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

GUI_APP_MAIN
{
	PainterText().Run();
}


but nothing.... Is not it possible that some new addition to your code is overwritting the cachec? Some dangling pointer perhaps?

Mirek
Re: Strange issue with text in Painter [message #50888 is a reply to message #50884] Sat, 12 January 2019 13:14 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Tom1 wrote on Fri, 11 January 2019 18:50
mirek wrote on Fri, 11 January 2019 16:43

#if 1
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
		DDUMP(chp.glyph);
		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


(If error is here, it should also assert....)


Strangely enough, this did not exhibit the problem at all. There are no buggy letters, as far as I could tell from looking around the map for 30 minutes. No asserts either, but that is to be expected as the problem did not surface here...


Well, that is something we can work with...

First of all, it would be nice to make sure this really makes differences. Change to #if 0 to resolve this.

If this is positive, I would set back to #if 1, retest, if problem is gone, then start removing lines of testing code from the last one until the problem reappears. That should give us some clue...

Mirek
Re: Strange issue with text in Painter [message #50890 is a reply to message #50888] Sat, 12 January 2019 14:57 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi,

Yes, I will follow your instructions... starting on Monday.

The absolute worst case scenario for me is if I have any pointer issues and corruption of memory thereby.

Late last night I started to think that I may have turned off PROTECT flag simultaneously when switching again to DEBUG mode for the test. This may have contributed to disappearance of the problem too. This is something I will have to check first thing on Monday. I mean the effect of working with and without PROTECT.

Anyway, I will keep digging. And I wish to thank you for your effort on this. (Hope I have not wasted your time with some stupid mistake of my own.)

Thanks and best regards,

Tom
Re: Strange issue with text in Painter [message #50902 is a reply to message #50890] Mon, 14 January 2019 09:58 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Hi Mirek,

OK, here's the situation. Using PROTECT or not does not have any effect on this issue. Neither does the compiler; MSBT17 and MSBT17x64 both work the same.

After starting to comment out the lines from the bottom of the sequence, PaintCharacter() proved to be the line required for correct operation. Commenting it out it brought the problem back:
#if 1
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		PaintCharacter(chp, Pointf(0, 0), ch, fnt); // <<-- Required for correct rendering
//		DDUMP(chp.glyph);
//		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


Any suggestions, how I should proceed?

Best regards,

Tom
Re: Strange issue with text in Painter [message #50903 is a reply to message #50902] Mon, 14 January 2019 10:13 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Tom1 wrote on Mon, 14 January 2019 09:58
Hi Mirek,

OK, here's the situation. Using PROTECT or not does not have any effect on this issue. Neither does the compiler; MSBT17 and MSBT17x64 both work the same.

After starting to comment out the lines from the bottom of the sequence, PaintCharacter() proved to be the line required for correct operation. Commenting it out it brought the problem back:
#if 1
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		PaintCharacter(chp, Pointf(0, 0), ch, fnt); // <<-- Required for correct rendering
//		DDUMP(chp.glyph);
//		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


Any suggestions, how I should proceed?

Best regards,

Tom


Try this:

#ifdef 1
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		DDUMP(ValueTo< Vector<float> >(v));
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		extern HFONT GetWin32Font(Font fnt, int angle);
		GetWin32Font(fnt, 0);
//		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
//		DDUMP(chp.glyph);
//		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


GetWin32Font is called by PaintCharacter and has some caching inside too, maybe that is the one that is causing the trouble. Of course, if calling it fixes the problem, try to comment and uncomment...

[Updated on: Mon, 14 January 2019 10:13]

Report message to a moderator

Re: Strange issue with text in Painter [message #50904 is a reply to message #50903] Mon, 14 January 2019 10:18 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
mirek wrote on Mon, 14 January 2019 11:13
...
Try this:

#ifdef 1
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		DDUMP(ValueTo< Vector<float> >(v));
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		extern HFONT GetWin32Font(Font fnt, int angle);
		GetWin32Font(fnt, 0);
//		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
//		DDUMP(chp.glyph);
//		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


GetWin32Font is called by PaintCharacter and has some caching inside too, maybe that is the one that is causing the trouble. Of course, if calling it fixes the problem, try to comment and uncomment...


This does not fix the issue.

BR,

Tom
Re: Strange issue with text in Painter [message #50905 is a reply to message #50904] Mon, 14 January 2019 10:26 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Tom1 wrote on Mon, 14 January 2019 10:18
mirek wrote on Mon, 14 January 2019 11:13
...
Try this:

#ifdef 1
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		DDUMP(ValueTo< Vector<float> >(v));
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		extern HFONT GetWin32Font(Font fnt, int angle);
		GetWin32Font(fnt, 0);
//		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
//		DDUMP(chp.glyph);
//		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


GetWin32Font is called by PaintCharacter and has some caching inside too, maybe that is the one that is causing the trouble. Of course, if calling it fixes the problem, try to comment and uncomment...


This does not fix the issue.

BR,

Tom


What happens if you do

void PaintCharacter(Painter& sw, const Pointf& p, int chr, Font font)
{
	GlyphInfo gi = GetGlyphInfo(font, chr);
	PaintCharPath pw;
	pw.sw = &sw;
	if(gi.IsNormal())
		font.Render(pw, p.x, p.y, chr);
/*	else
	if(gi.IsReplaced()) {
		Font fnt = font;
		fnt.Face(gi.lspc);
		fnt.Height(gi.rspc);
		fnt.Render(pw, p.x, p.y + font.GetAscent() - fnt.GetAscent(), chr);
	}
	else
	if(gi.IsComposed()) {
		ComposedGlyph cg;
		Compose(font, chr, cg);
		font.Render(pw, p.x, p.y, cg.basic_char);
		sw.Div();
		cg.mark_font.Render(pw, p.x + cg.mark_pos.x, p.y + cg.mark_pos.y, cg.mark_char);
	}*/
	sw.EvenOdd(true);
}


This should have no impact at all; we are testing branches that do character replacements if characters are missing. But I guess it is worth checking (as everything else fails).
Re: Strange issue with text in Painter [message #50906 is a reply to message #50905] Mon, 14 January 2019 10:28 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Another idea to test:

#ifdef 1
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		DDUMP(ValueTo< Vector<float> >(v));
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		GetGlyphInfo(fnt, ch);
//		GetWin32Font(fnt, 0);
//		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
		DDUMP(chp.glyph);
		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


Does this fix the issue? (GetGlyphInfo is another caching function called from PaintCharacter).

Mirek
Re: Strange issue with text in Painter [message #50907 is a reply to message #50905] Mon, 14 January 2019 10:39 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Yes, this does not have any effect what so ever. (I mean the Painter.cpp :: PaintCharacter() change.)

BR, Tom

[Updated on: Mon, 14 January 2019 10:40]

Report message to a moderator

Re: Strange issue with text in Painter [message #50908 is a reply to message #50906] Mon, 14 January 2019 10:42 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
mirek wrote on Mon, 14 January 2019 11:28
Another idea to test:

#ifdef 1
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		DDUMP(ValueTo< Vector<float> >(v));
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;
		GetGlyphInfo(fnt, ch);
//		GetWin32Font(fnt, 0);
//		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
		DDUMP(chp.glyph);
		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


Does this fix the issue? (GetGlyphInfo is another caching function called from PaintCharacter).

Mirek


This does not fix the issue either. (Additionally I had to comment out the ASSERT, as the chp.glyph is not initialized to compare correctly with v.)

BR, Tom
Re: Strange issue with text in Painter [message #50909 is a reply to message #50908] Mon, 14 January 2019 10:47 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
What about this:

#ifdef 1
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		DDUMP(ValueTo< Vector<float> >(v));
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;

		struct PaintCharPath : FontGlyphConsumer {
			Painter *sw;
			
			virtual void Move(Pointf p) {
				sw->Move(p);
			}
			virtual void Line(Pointf p) {
				sw->Line(p);
			}
			virtual void Quadratic(Pointf p1, Pointf p2) {
				sw->Quadratic(p1, p2);
			}
			virtual void Cubic(Pointf p1, Pointf p2, Pointf p3) {
				sw->Cubic(p1, p2, p3);
			}
			virtual void Close() {
				sw->Close();
			}
		} pw;
		pw.sw = &chp;
		fnt.Render(pw, 0, 0, ch);
//		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
//		DDUMP(chp.glyph);
//		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


(We are trying to identify which part of PaintCharacter makes the difference...)
Re: Strange issue with text in Painter [message #50910 is a reply to message #50909] Mon, 14 January 2019 11:01 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Tried. Now the error appears if "fnt.Render(pw, 0, 0, ch);" is commented out from the above.

BR, Tom
Re: Strange issue with text in Painter [message #50911 is a reply to message #50910] Mon, 14 January 2019 11:07 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Tom1 wrote on Mon, 14 January 2019 11:01
Tried. Now the error appears if "fnt.Render(pw, 0, 0, ch);" is commented out from the above.

BR, Tom


Getting closer, but still no clue....

#ifdef 1
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		DDUMP(ValueTo< Vector<float> >(v));
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;

		struct PaintCharPath : FontGlyphConsumer {
			Painter *sw;
			
			virtual void Move(Pointf p) {
				sw->Move(p);
			}
			virtual void Line(Pointf p) {
				sw->Line(p);
			}
			virtual void Quadratic(Pointf p1, Pointf p2) {
				sw->Quadratic(p1, p2);
			}
			virtual void Cubic(Pointf p1, Pointf p2, Pointf p3) {
				sw->Cubic(p1, p2, p3);
			}
			virtual void Close() {
				sw->Close();
			}
		} pw;
		pw.sw = &chp;
		void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt);
		RenderCharacterSys(pw, 0, 0, ch, fnt);
//		fnt.Render(pw, 0, 0, ch);
//		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
//		DDUMP(chp.glyph);
//		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif


Now if RenderCharacterSys here is our 'toggle', I suggest start commenting out its internals to see what really makes the difference...

Mirek
Re: Strange issue with text in Painter [message #50912 is a reply to message #50911] Mon, 14 January 2019 11:11 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Oh, sorry about the part about "commenting out" - that would not work (because we are using it for the desired rendering as well).

What we need to do is to copy it and THEN start removing...

double fx_to_dbl(const FIXED& p);
Pointf fx_to_dbl(const Pointf& pp, const POINTFX& p);

struct sMakeGlyph : LRUCache<Value, GlyphKey>::Maker {
	GlyphKey gk;

	GlyphKey Key() const     { return gk; }
	int      Make(Value& v) const {
		GlyphPainter gp;
		gp.move = gp.pos = Null;
		gp.tolerance = gk.tolerance;
		PaintCharacter(gp, Pointf(0, 0), gk.chr, gk.fnt);
		int sz = gp.glyph.GetCount() * 4;
		v = RawPickToValue(pick(gp.glyph));
		return sz;
	}
};

void RenderCharPath2(const char* gbuf, unsigned total_size, FontGlyphConsumer& sw, double xx, double yy)
{
	const char* cur_glyph = gbuf;
	const char* end_glyph = gbuf + total_size;
	Pointf pp(xx, yy);
	while(cur_glyph < end_glyph) {
		const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;
		const char* end_poly = cur_glyph + th->cb;
		const char* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);
		sw.Move(fx_to_dbl(pp, th->pfxStart));
		while(cur_poly < end_poly) {
			const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;
			if (pc->wType == TT_PRIM_LINE)
				for(int i = 0; i < pc->cpfx; i++)
					sw.Line(fx_to_dbl(pp, pc->apfx[i]));
			if (pc->wType == TT_PRIM_QSPLINE)
				for(int u = 0; u < pc->cpfx - 1; u++) {
					Pointf b = fx_to_dbl(pp, pc->apfx[u]);
					Pointf c = fx_to_dbl(pp, pc->apfx[u + 1]);
					if (u < pc->cpfx - 2)
						c = Mid(b, c);
					sw.Quadratic(b, c);
				}
			cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
		}
		sw.Close();
		cur_glyph += th->cb;
    }
}

HFONT GetWin32Font(Font fnt, int angle);
HDC   Win32_IC();

void RenderCharacterSys2(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt)
{
	HFONT hfont = GetWin32Font(fnt, 0);
	if(hfont) {
		HDC hdc = Win32_IC();
		HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
		GLYPHMETRICS gm;
		MAT2 m_matrix;
		memset(&m_matrix, 0, sizeof(m_matrix));
		m_matrix.eM11.value = 1;
		m_matrix.eM22.value = 1;
		int gsz = GetGlyphOutlineW(hdc, ch, GGO_NATIVE, &gm, 0, NULL, &m_matrix);
		if(gsz < 0)
			return;
		StringBuffer gb(gsz);
		gsz = GetGlyphOutlineW(hdc, ch, GGO_NATIVE, &gm, gsz, ~gb, &m_matrix);
		if(gsz < 0)
			return;
		RenderCharPath2(~gb, gsz, sw, x, y + fnt.GetAscent());
		::SelectObject(hdc, ohfont);
	}
}

void ApproximateChar(LinearPathConsumer& t, Pointf at, int ch, Font fnt, double tolerance)
{
	PAINTER_TIMING("ApproximateChar");
	Value v;
	INTERLOCKED {
		PAINTER_TIMING("ApproximateChar::Fetch");
		static LRUCache<Value, GlyphKey> cache;
		cache.Shrink(500000);
		sMakeGlyph h;
		h.gk.fnt = fnt;
		h.gk.chr = ch;
		h.gk.tolerance = tolerance;
		v = cache.Get(h);
#ifdef _DEBUG
		DLOG("==== ApproximateChar " << ch << " " << (char)ch << " " << fnt << ", tolerance: " << tolerance);
		DDUMP(ValueTo< Vector<float> >(v));
		GlyphPainter chp;
		chp.move = chp.pos = Null;
		chp.tolerance = tolerance;

		struct PaintCharPath : FontGlyphConsumer {
			Painter *sw;
			
			virtual void Move(Pointf p) {
				sw->Move(p);
			}
			virtual void Line(Pointf p) {
				sw->Line(p);
			}
			virtual void Quadratic(Pointf p1, Pointf p2) {
				sw->Quadratic(p1, p2);
			}
			virtual void Cubic(Pointf p1, Pointf p2, Pointf p3) {
				sw->Cubic(p1, p2, p3);
			}
			virtual void Close() {
				sw->Close();
			}
		} pw;
		pw.sw = &chp;
		RenderCharacterSys2(pw, 0, 0, ch, fnt);
//		fnt.Render(pw, 0, 0, ch);
//		PaintCharacter(chp, Pointf(0, 0), ch, fnt);
//		DDUMP(chp.glyph);
//		ASSERT(ValueTo< Vector<float> >(v) == chp.glyph);
#endif
	}
	const Vector<float>& g = ValueTo< Vector<float> >(v);
	int i = 0;
	while(i < g.GetCount()) {
		Pointf p;
		p.x = g[i++];
		if(p.x > 1e30) {
			p.x = g[i++];
			p.y = g[i++];
			t.Move(p + at);
		}
		else {
			PAINTER_TIMING("ApproximateChar::Line");
			p.y = g[i++];
			t.Line(p + at);
		}
	}
}


It this still 'toggles', start commenting from RenderCharPath2 call up...

[Updated on: Mon, 14 January 2019 11:12]

Report message to a moderator

Re: Strange issue with text in Painter [message #50913 is a reply to message #50912] Mon, 14 January 2019 11:30 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
Commenting out this breaks rendering:
		// RenderCharPath2(~gb, gsz, sw, x, y + fnt.GetAscent());


I'll try to chop that one to slices next...

BR, Tom
Re: Strange issue with text in Painter [message #50915 is a reply to message #50913] Mon, 14 January 2019 11:32 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Also try

RenderCharPath2(~gb, gsz, sw, x, y/* + fnt.GetAscent()*/);
Re: Strange issue with text in Painter [message #50916 is a reply to message #50915] Mon, 14 January 2019 11:41 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14290
Registered: November 2005
Ultimate Member
Thinking about it, I have suspiction that maybe RawPickToValue might have to do something with all that...

What about this:

struct sMakeGlyph : LRUCache<String, GlyphKey>::Maker {
	GlyphKey gk;

	GlyphKey Key() const     { return gk; }
	int      Make(String& v) const {
		GlyphPainter gp;
		gp.move = gp.pos = Null;
		gp.tolerance = gk.tolerance;
		PaintCharacter(gp, Pointf(0, 0), gk.chr, gk.fnt);
		int sz = gp.glyph.GetCount() * 4;
		v.Set((char *)gp.glyph.begin(), sizeof(float) * gp.glyph.GetCount());
		return sz;
	}
};

void ApproximateChar(LinearPathConsumer& t, Pointf at, int ch, Font fnt, double tolerance)
{
	PAINTER_TIMING("ApproximateChar");
	String v;
	INTERLOCKED {
		PAINTER_TIMING("ApproximateChar::Fetch");
		static LRUCache<String, GlyphKey> cache;
		cache.Shrink(500000);
		sMakeGlyph h;
		h.gk.fnt = fnt;
		h.gk.chr = ch;
		h.gk.tolerance = tolerance;
		v = cache.Get(h);
	}
	int i = 0;
	int count = v.GetCount() / sizeof(float);
	const float *g = (const float *)~v;
	while(i < count) {
		Pointf p;
		p.x = g[i++];
		if(p.x > 1e30) {
			p.x = g[i++];
			p.y = g[i++];
			t.Move(p + at);
		}
		else {
			PAINTER_TIMING("ApproximateChar::Line");
			p.y = g[i++];
			t.Line(p + at);
		}
	}
}
Re: Strange issue with text in Painter [message #50917 is a reply to message #50915] Mon, 14 January 2019 11:49 Go to previous messageGo to next message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
mirek wrote on Mon, 14 January 2019 12:32
Also try

RenderCharPath2(~gb, gsz, sw, x, y/* + fnt.GetAscent()*/);


This does not make any difference.

Tom
Re: Strange issue with text in Painter [message #50919 is a reply to message #50917] Mon, 14 January 2019 11:52 Go to previous messageGo to previous message
Tom1
Messages: 1319
Registered: March 2007
Ultimate Contributor
This shows the problem:
void RenderCharPath2(const char* gbuf, unsigned total_size, FontGlyphConsumer& sw, double xx, double yy)
{
	const char* cur_glyph = gbuf;
	const char* end_glyph = gbuf + total_size;
	Pointf pp(xx, yy);
	while(cur_glyph < end_glyph) {
		const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;
		const char* end_poly = cur_glyph + th->cb;
		const char* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);
		sw.Move(fx_to_dbl(pp, th->pfxStart));
/*		while(cur_poly < end_poly) {
			const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;
			if (pc->wType == TT_PRIM_LINE)
				for(int i = 0; i < pc->cpfx; i++)
					sw.Line(fx_to_dbl(pp, pc->apfx[i]));
			if (pc->wType == TT_PRIM_QSPLINE)
				for(int u = 0; u < pc->cpfx - 1; u++) {
					Pointf b = fx_to_dbl(pp, pc->apfx[u]);
					Pointf c = fx_to_dbl(pp, pc->apfx[u + 1]);
					if (u < pc->cpfx - 2)
						c = Mid(b, c);
					sw.Quadratic(b, c);
				}
			cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
		}
*/		sw.Close();
		cur_glyph += th->cb;
    }
}


This renders OK:

void RenderCharPath2(const char* gbuf, unsigned total_size, FontGlyphConsumer& sw, double xx, double yy)
{
	const char* cur_glyph = gbuf;
	const char* end_glyph = gbuf + total_size;
	Pointf pp(xx, yy);
	while(cur_glyph < end_glyph) {
		const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;
		const char* end_poly = cur_glyph + th->cb;
		const char* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);
		sw.Move(fx_to_dbl(pp, th->pfxStart));
		while(cur_poly < end_poly) {
			const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;
/*			if (pc->wType == TT_PRIM_LINE)
				for(int i = 0; i < pc->cpfx; i++)
					sw.Line(fx_to_dbl(pp, pc->apfx[i]));
			if (pc->wType == TT_PRIM_QSPLINE)
				for(int u = 0; u < pc->cpfx - 1; u++) {
					Pointf b = fx_to_dbl(pp, pc->apfx[u]);
					Pointf c = fx_to_dbl(pp, pc->apfx[u + 1]);
					if (u < pc->cpfx - 2)
						c = Mid(b, c);
					sw.Quadratic(b, c);
				}
*/			cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
		}
		sw.Close();
		cur_glyph += th->cb;
    }
}


I will now check the next suggestion with raw pick.

BR, Tom
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: Fri May 01 00:57:14 GMT+2 2026

Total time taken to generate the page: 0.01820 seconds