Discussion:
Circle drawing on Cocoa
Neil Hodgson
2014-01-16 09:10:41 UTC
Permalink
Circles drawn on Cocoa for the folding margin or other markers have looked quite poor. This should now be fixed by using an API meant for drawing ellipses instead of a series of bezier curves. The curve approach appears to be a holdover from the Carbon implementation.

This image shows before on the left and after on the right:
Loading Image...

The code was much simplified by this patch:
http://sourceforge.net/p/scintilla/code/ci/19b2a76a906397eb8a3ee5dd95d90e42508f8e04/

Neil
--
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scintilla-interest+***@googlegroups.com.
To post to this group, send email to scintilla-***@googlegroups.com.
Visit this group at http://groups.google.com/group/scintilla-interest.
For more options, visit https://groups.google.com/groups/opt_out.
Neil Hodgson
2014-01-16 23:45:41 UTC
Permalink
There’s an issue with drawing circles on GTK+ as well, with SC_MARK_CIRCLE* markers appearing off-centre with the internal ‘+‘ and ‘-‘ hitting the side. This problem was solved once before with this patch:
https://sourceforge.net/p/scintilla/code/ci/03b1652d0f2f573f9c945c5990b62891660e60ee/

The solution appears to be to revert the part of the patch in the Ellipse method:

diff -r daba3880ead4 gtk/PlatGTK.cxx
--- a/gtk/PlatGTK.cxx Tue Jan 14 19:10:31 2014 +1100
+++ b/gtk/PlatGTK.cxx Fri Jan 17 10:00:47 2014 +1100
@@ -822,7 +822,7 @@

void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) {
PenColour(back);
- cairo_arc(context, (rc.left + rc.right) / 2 + 0.5, (rc.top + rc.bottom) / 2 + 0.5,
+ cairo_arc(context, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2,
Platform::Minimum(rc.Width(), rc.Height()) / 2, 0, 2*kPi);
cairo_fill_preserve(context);
PenColour(fore);

While this regression may have occurred because of changes to the underlying GTK+/Cairo libraries, its possible that something like drawing a circle with odd/even width could cause it. I have been unable to find any widths that don’t look wrong with the current code and that don’t look correct after the patch, checking with both GTK+ 2 and GTK+ 3 on current Mint. If GTK+ users can check the appearance of circular fold indicators and report whether they currently appear correct on their setup then that would help determine whether to commit this patch.

This changes the appearance as shown in this image with before on the left and after on the right.



The image also shows a potential change to drawing SC_MARK_ARROWS indicators that scales the arrows to fit the line height and also avoids drawing one arm of each arrow longer than the other on Cocoa. The weight of the strokes is more uniform with this patch on Windows/Direct2D and Cairo.

diff -r daba3880ead4 src/LineMarker.cxx
--- a/src/LineMarker.cxx Tue Jan 14 19:10:31 2014 +1100
+++ b/src/LineMarker.cxx Fri Jan 17 10:31:28 2014 +1100
@@ -355,10 +355,12 @@
} else if (markType == SC_MARK_ARROWS) {
surface->PenColour(fore);
int right = centreX - 2;
+ const int armLength = dimOn2-1;
for (int b=0; b<3; b++) {
- surface->MoveTo(right - 4, centreY - 4);
- surface->LineTo(right, centreY);
- surface->LineTo(right - 5, centreY + 5);
+ surface->MoveTo(right, centreY);
+ surface->LineTo(right - armLength, centreY - armLength);
+ surface->MoveTo(right, centreY);
+ surface->LineTo(right - armLength, centreY + armLength);
right += 4;
}
} else if (markType == SC_MARK_SHORTARROW) {

Neil
--
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scintilla-interest+***@googlegroups.com.
To post to this group, send email to scintilla-***@googlegroups.com.
Visit this group at http://groups.google.com/group/scintilla-interest.
For more options, visit https://groups.google.com/groups/opt_out.
Colomban Wendling
2014-01-17 01:18:08 UTC
Permalink
Hi,
There’s an issue with drawing circles on GTK+ as well,
with SC_MARK_CIRCLE* markers appearing off-centre with the internal ‘+‘
and ‘-‘ hitting the side. This problem was solved once before with this
https://sourceforge.net/p/scintilla/code/ci/03b1652d0f2f573f9c945c5990b62891660e60ee/
Is it me or this patch also disabled the use of Cairo even with GTK >=
2.22? If it's the case, it could have hidden that the change wasn't
good for the arc.
diff -r daba3880ead4 gtk/PlatGTK.cxx
--- a/gtk/PlatGTK.cxxTue Jan 14 19:10:31 2014 +1100
+++ b/gtk/PlatGTK.cxxFri Jan 17 10:00:47 2014 +1100
@@ -822,7 +822,7 @@
void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore,
ColourDesired back) {
PenColour(back);
-cairo_arc(context, (rc.left + rc.right) / 2 + 0.5, (rc.top + rc.bottom)
/ 2 + 0.5,
+cairo_arc(context, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2,
Platform::Minimum(rc.Width(), rc.Height()) / 2, 0, 2*kPi);
cairo_fill_preserve(context);
PenColour(fore);
While this regression may have occurred because of changes to the
underlying GTK+/Cairo libraries, its possible that something like
drawing a circle with odd/even width could cause it. I have been unable
to find any widths that don’t look wrong with the current code and that
don’t look correct after the patch, checking with both GTK+ 2 and GTK+ 3
on current Mint. If GTK+ users can check the appearance of circular fold
indicators and report whether they currently appear correct on their
setup then that would help determine whether to commit this patch.
I just tested with Geany (Scintilla 3.3.6 currently) and I can confirm
that the rounded fold markers were off (and blurry) and that this fixes
it. Both with GTK 2.24.22 and 3.8.6, using Cairo 1.12.16.
I also tried various margin widths and all looked good, even odd ones.

Also, I'm not surprised that this change improves things actually,
because here the arguments define the *center* of the circle and not the
position of the line, so moving the center doesn't sound sensible. If
anything, it's the radius that should be adjusted, but this doesn't seem
to be needed -- and actually, tweaking it by half a pixel simply places
the drawn line between pixels as expected (and then looks ugly).
This changes the appearance as shown in this image with before on the
left and after on the right.
I also see (no change between the 2 version tho) that
SC_MARK_[LT]CORNERCURVE look quite bad (and I can confirm it here), do
you know why or have you tried to improve those?
The image also shows a potential change to drawing SC_MARK_ARROWS
indicators that scales the arrows to fit the line height and also avoids
drawing one arm of each arrow longer than the other on Cocoa. The weight
of the strokes is more uniform with this patch on Windows/Direct2D and
Cairo.
Indeed, tested and it does look better to be (like on your image, again).


Regards,
Colomban
--
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scintilla-interest+***@googlegroups.com.
To post to this group, send email to scintilla-***@googlegroups.com.
Visit this group at http://groups.google.com/group/scintilla-interest.
For more options, visit https://groups.google.com/groups/opt_out.
Matthew Brush
2014-01-17 03:44:18 UTC
Permalink
Post by Neil Hodgson
https://sourceforge.net/p/scintilla/code/ci/03b1652d0f2f573f9c945c5990b62891660e60ee/
diff -r daba3880ead4 gtk/PlatGTK.cxx
--- a/gtk/PlatGTK.cxx Tue Jan 14 19:10:31 2014 +1100
+++ b/gtk/PlatGTK.cxx Fri Jan 17 10:00:47 2014 +1100
@@ -822,7 +822,7 @@
void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) {
PenColour(back);
- cairo_arc(context, (rc.left + rc.right) / 2 + 0.5, (rc.top + rc.bottom) / 2 + 0.5,
+ cairo_arc(context, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2,
Platform::Minimum(rc.Width(), rc.Height()) / 2, 0, 2*kPi);
cairo_fill_preserve(context);
PenColour(fore);
While this regression may have occurred because of changes to the underlying GTK+/Cairo libraries, its possible that something like drawing a circle with odd/even width could cause it. I have been unable to find any widths that don’t look wrong with the current code and that don’t look correct after the patch, checking with both GTK+ 2 and GTK+ 3 on current Mint. If GTK+ users can check the appearance of circular fold indicators and report whether they currently appear correct on their setup then that would help determine whether to commit this patch.
Looks weird pre-patch and normal post-patch here on Xubuntu 13.10 with
both GTK+ 2.24.20 and 3.8.6. Probably that
pixel-snapping/offset-by-point-five trick is not useful with arcs, I've
only ever seen applied to straight lines personally.

Note: I only looked at round fold-margin symbols in SciTE from
Mercurial, I didn't check to see if it broke anything somewhere else in
other parts of the program.

Cheers,
Matthew Brush
--
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scintilla-interest+***@googlegroups.com.
To post to this group, send email to scintilla-***@googlegroups.com.
Visit this group at http://groups.google.com/group/scintilla-interest.
For more options, visit https://groups.google.com/groups/opt_out.
Neil Hodgson
2014-01-18 00:25:05 UTC
Permalink
These changes are now committed.

Also fixed Windows/Direct2D which had been drawing circles smaller with a radius 1 less than other platforms.

The order of drawing for SC_MARK_CIRCLE* was changed in some cases so that the circles are always drawn after connecting lines which covers up extraneous pixels.

Commits:
http://sourceforge.net/p/scintilla/code/ci/452a37171993d8884b5a7100037d8dd5403b55dd/
http://sourceforge.net/p/scintilla/code/ci/a627d901088bae7889671262bae23e45282bab87/
http://sourceforge.net/p/scintilla/code/ci/93a883f42d6ccf1156150439c18518701ac4956a/
Note: I only looked at round fold-margin symbols in SciTE from Mercurial, I didn't check to see if it broke anything somewhere else in other parts of the program.
The only callers of Ellipse are in LineMarker.cxx and only for drawing circular fold markers SC_MARK_CIRCLEPLUS* and SC_MARK_CIRCLEMINUS* as well as for the circular marker SC_MARK_CIRCLE.

Here is a SciTE Lua function for showing all the fixed visible markers. After copying into the script file, the lineStart value needs to be set.

function ShowAllMarkers()
local lineStart = 220 -- Set this to number of line before SC_MARK_CIRCLE
local markers = {

SC_MARK_CIRCLE,
SC_MARK_ROUNDRECT,
SC_MARK_SMALLRECT,
SC_MARK_SHORTARROW,
31,
SC_MARK_FULLRECT,
SC_MARK_LEFTRECT,
SC_MARK_BACKGROUND,
SC_MARK_UNDERLINE,
SC_MARK_DOTDOTDOT,
SC_MARK_ARROWS,
SC_MARK_ARROW,
SC_MARK_ARROWDOWN,
SC_MARK_PLUS,
SC_MARK_MINUS,
SC_MARK_BOXPLUS,
SC_MARK_BOXPLUSCONNECTED,
SC_MARK_BOXMINUS,
SC_MARK_BOXMINUSCONNECTED,
SC_MARK_CIRCLEPLUS,
SC_MARK_CIRCLEPLUSCONNECTED,
SC_MARK_CIRCLEMINUS,
SC_MARK_CIRCLEMINUSCONNECTED,
SC_MARK_VLINE,
SC_MARK_LCORNER,
SC_MARK_TCORNER,
SC_MARK_LCORNERCURVE,
SC_MARK_TCORNERCURVE

}
editor.MarginMaskN[1] = 0x7fffffff
local line = 0
for i, v in ipairs(markers) do
local m = v
editor:MarkerDeleteAll(line)
editor:MarkerDefine(line, m)
if m == 31 then
editor.MarkerFore[line] = 0x0000BE
editor.MarkerBack[line] = 0x4040E2
elseif line < 15 then
editor.MarkerFore[line] = 0x000000
editor.MarkerBack[line] = 0xFFC0A0
else
editor.MarkerFore[line] = 0xFFC0A0
editor.MarkerBack[line] = 0x000000
end
editor:MarkerAdd(line+lineStart, line)
line = line + 1
end
end
--
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scintilla-interest+***@googlegroups.com.
To post to this group, send email to scintilla-***@googlegroups.com.
Visit this group at http://groups.google.com/group/scintilla-interest.
For more options, visit https://groups.google.com/groups/opt_out.
Loading...