[cairo] PATCH cairo-www: Simpler explanation for how to get sharp, single-pixel-wide lines
Olaf Schmidt
ng at vbRichClient.com
Wed May 17 19:28:22 UTC 2017
Am 17.05.2017 um 13:27 schrieb Guillermo Rodriguez:
>>> It occurs because integer coordinates map to points half way
>>> between sample point locations ...
>>
>> That’s a common misconception.
>
> It's taken straight from the current Cairo FAQ.
>
> Again: A common use case is that you want to have antialiasing in
> general BUT at the same time be able to draw 1 pixel wide vertical or
> horizontal lines that don't look "blurry". The current text describes
> an approach which achieves exactly that by adjusting endpoints of
> horizontal / vertical lines by 0.5 in the appropriate direction. That
> gets you perfect sharp, single-pixel-wide vertical and horizontal
> lines without the need to turn off antialiasing. Your "simpler
> explanation" proposal misses that completely.
To "underline" the above (which is the suggestion I've followed in
a WidgetEngine) - here's a ScreenShot which shows both cases:
http://vbRichClient.com/Downloads/WidgetRenderQuality.png
- btnHello1 following the more "general purpose" suggestion above
- btnHello2 following the suggestion of Lawrence (which has its
place, but I'd think it should only be mentioned "in addition":
(in case one wants to render straight horizontal or vertical lines only)
For those who want to run the little Mini-App which produced the
ScreenShot, below is the *.vbs-Code (sorry for the "Win-only" example).
The AntiAliasing-switchery is done in the Paint-Event of the little
cwSimpleButton-Class at the bottom...
Set New_c = CreateObject("vbRichClient5.cConstructor") 'Main-Constructor
Set Cairo = New_c.Cairo 'ensure the global Cairo-Namespace-Entrypoint
Set Form=Cairo.WidgetForms.Create(2, "Widget-Renderquality", , 320, 240)
WScript.ConnectObject Form, "Form_" '<- EventSink-Prefix and -Binding
the VBScript-way
Form.Show
Cairo.WidgetForms.EnterMessageLoop 'here we enter the message-pump of
our little Application
Sub Form_Load()
Form.Widgets.Add New cwSimpleButton,"btnHello1", 10, 10, 100, 25
'normal AntiAliasing
Form.Widgets.Add(New cwSimpleButton,"btnHello2", 10, 40, 100,
25).AntiAliasOff=True
End Sub
'this Event travels through all the Parent-Widgets of a nested
Widget-Hierarchy up to the Form
Sub Form_BubblingEvent(Sender, EventName, P1, P2, P3, P4, P5, P6, P7)
Select Case EventName
Case "W_Paint": Sender.Paint P1, P4, P5 're-route to the Class
Case "W_Click": If TypeName(Sender) = "cwSimpleButton" Then MsgBox
Sender.Widget.Key
Case "W_MouseEnter", "W_MouseLeave", "W_MouseDown", "W_MouseUp":
Sender.Widget.Refresh
End Select
End Sub
'just to ensure the missing IIf()-Function in the VBScript-Context
Function IIf(Cond, ResultIfTrue, ResultIfFalse)
If Cond Then IIf = ResultIfTrue Else IIf = ResultIfFalse
End Function
'a cairo-Widget-Class (for a simple ownerdrawn Command-Button)
Class cwSimpleButton
Private W 'define and instantiate the internal W-WidgetBase
Private Sub Class_Initialize(): Set W = Cairo.WidgetBase: End Sub
'below the two Properties, any cwClass needs to implement
Property Get Widget(): Set Widget = W: End Property
Property Get Widgets(): Set Widgets = W.Widgets: End Property
Public AntiAliasOff 'define a Property to allow DrawMode-switching
from outside
Sub Paint(ByVal CC, ByVal dx, ByVal dy)
Dim State
State = IIf(W.Root.MouseKeyDown And W.MouseOver, 1, 0) Or
IIf(W.MouseOver, 2, 0)
If AntiAliasOff Then CC.AntiAlias = 1 'CAIRO_ANTIALIAS_NONE
Cairo.Theme.DrawTo (CC), (W), 0, State, 0, 0, dx, dy, 2 'draw a
themed Button-Face first
CC.SetSourceColor W.BorderColor 'and now the surrounding Border
CC.SetLineWidth 2
CC.RoundedRect 0, 0, dx, dy, 4, True '<- True to take care of
"sharp coord-placement"
CC.Stroke
W.SelectFontSettingsInto (CC) 'select all current
W.Font*-Properties into the CairoContext
CC.DrawText 1, 1, dx, dy, W.Key, , 2, 2, 1 'a Caption (using the
W.Key to simplify things)
End Sub
End Class
HTH
Olaf
More information about the cairo
mailing list