Re: [racket-users] [racket][draw] some APIs should be more open

2017-04-13 Thread WarGrey Gyoudmon Ju
Sorry I didn't describe my idea clearly before.

Actually, in my framework (I've been writing a CSS Engine), all those
objects are immutable and singular by design. The problem is, there is no
way for client application to tell those primary classes "The object is
already immutable".

(define rgba%
  (class inspectable-color%
(init [red  (random 255)]
   [green (random 255)]
   [blue (random 255)]
   [alpha 1.0])

(init-field [immutable? #true])

(super-make-object red green blue alpha)

(define/override (set red green blue [alpha 1.0])
  (when immutable? (error 'rgba% "color is immutable"))
  (super set red green blue alpha))

(define/override (copy-from src)
  (set (send this red) (send this green) (send this blue) (send this
alpha))
  this)

(define/override (is-immutable?)
  immutable?)

(define/override (inspect)
  (list (send this red) (send this green) (send this blue) (send this
alpha)


In this example, inspectable-color% is a subclass of color% and implements
`printable<%>` whose methods use the value of (inspect) to print its
instance. Here I have to add an extra field `immutable?` for overriding all
setter methods(This is what I meant "wordy code"), this is okay for client
application, but racket/draw still thinks the color is mutable since the
only way to make immutable color is calling (make-color) which use the
hidden public method (set-immutable).  Every time passing a custom color
object to Pen% and Brush%, it is copied.

For these simple object what I exactly asked for is to make (set-immutable)
method usable.

Font is the most complicated among them, even Pango cannot handle the
complexity well, this is a long term plan I will keep an eye on. For now,
since CSS Specification defines lots of font-relative units, and
racket/draw does not provide all the interface to obtain them(this is the
so-called "in-practical" situation mentioned by the spec). Just like
(get-handler)  exists widely in racket/draw and racket/gui, I wonder if it
is possible for font% to provide a same method, so that these duplicate
code are avoided:

(define make-desc+extent
(lambda [font-face font-size font-style font-weight]
  (define font-desc
(let ([face-is-family? (regexp-match #rx"," font-face)])
  (cond [(not face-is-family?) (pango_font_description_from_string
font-face)]
[else (let ([desc (pango_font_description_new)])
(pango_font_description_set_family desc font-face)
desc)])))
  (unless (eq? font-style 'normal) (pango_font_description_set_style
font-desc (~style font-style)))
  (unless (eq? font-weight 'normal) (pango_font_description_set_weight
font-desc (~weight font-weight)))
  (pango_font_description_set_absolute_size font-desc (* font-size
PANGO_SCALE))

  (define layout (or (unbox ) (and (set-box! 
(pango_cairo_create_layout cr)) (unbox 
  (pango_layout_set_font_description layout font-desc)

  (let ([baseline (pango_layout_get_baseline layout)])
(values font-desc baseline (λ [hint-char] (~extent layout baseline
hint-char))

  (define ~extent
(lambda [layout baseline hint-char]
  (pango_layout_set_text layout hint-char)
  (pango_layout_get_extents layout  )

  (define-values (x y width height) (~rectangle ))
  (define layout-height (PangoRectangle-height ))

  (values x y width height layout-height)))

or, just allow (get-text-extent) functions and methods returning the ink
metrics instead of the logical one.

I prefer the former.


On Wed, Apr 12, 2017 at 10:23 PM, George Neuner 
wrote:

>
> On 4/11/2017 10:41 PM, WarGrey Gyoudmon Ju wrote:
>
>> This is a little awkward, there are lots of simple classes defined in
>> racket/draw, font%, color%, pen%, brush% and so on. They just hold a group
>> of plain data, hence opportunities to be inspected easily. However by
>> default all classes are opaque, the easiest (and perhaps unique) way to
>> handle this is to inherit them and implement the `printable<%>` or
>> `writable<%>`.
>>
>> Despite the wordy code and wasting little runtime space, the major
>> problem is all those classes hide their (set-immutable) methods, even
>> worse, the immutability is checked through the private field. As a
>> consequence, subclasses of Pen% and Brush% copy color instances every time
>> to make them immutable (and opaque) again...
>>
>> So is it okay to open that interface?
>>
>
> A lot of graphic APIs - Windows, X, Display Postscript, etc. - discourage
> modifying a resource while the resource is selected in a drawing context.
>  Of course, you aren't actively prevented from doing it ... but bad things
> - including serious crashes - may happen if you touch something at exactly
> the wrong time.  Colors and pens are degenerate examples - the bitmaps
> associated with brushes and raster(ized) fonts are more representative of

Re: [racket-users] [racket][draw] some APIs should be more open

2017-04-12 Thread George Neuner


On 4/11/2017 10:41 PM, WarGrey Gyoudmon Ju wrote:
This is a little awkward, there are lots of simple classes defined in 
racket/draw, font%, color%, pen%, brush% and so on. They just hold a 
group of plain data, hence opportunities to be inspected easily. 
However by default all classes are opaque, the easiest (and perhaps 
unique) way to handle this is to inherit them and implement the 
`printable<%>` or `writable<%>`.


Despite the wordy code and wasting little runtime space, the major 
problem is all those classes hide their (set-immutable) methods, even 
worse, the immutability is checked through the private field. As a 
consequence, subclasses of Pen% and Brush% copy color instances every 
time to make them immutable (and opaque) again...


So is it okay to open that interface?


A lot of graphic APIs - Windows, X, Display Postscript, etc. - 
discourage modifying a resource while the resource is selected in a 
drawing context.   Of course, you aren't actively prevented from doing 
it ... but bad things - including serious crashes - may happen if you 
touch something at exactly the wrong time.  Colors and pens are 
degenerate examples - the bitmaps associated with brushes and 
raster(ized) fonts are more representative of the problem.


If you make the (Racket) objects mutable, I would worry that people 
might be tempted to mess with them at inappropriate times.  Raw graphic 
APIs don't protect you from being stupid ... Racket's API at least tries 
to.  I suppose an alternative would be to lock the objects while they 
are selected, but I don't know how easy that would be to implement.


Just my $0.02

George

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] [racket][draw] some APIs should be more open

2017-04-12 Thread Matthias Felleisen

Why should fonts and colors be mutable? 


> On Apr 11, 2017, at 10:41 PM, WarGrey Gyoudmon Ju  
> wrote:
> 
> This is a little awkward, there are lots of simple classes defined in 
> racket/draw, font%, color%, pen%, brush% and so on. They just hold a group of 
> plain data, hence opportunities to be inspected easily. However by default 
> all classes are opaque, the easiest (and perhaps unique) way to handle this 
> is to inherit them and implement the `printable<%>` or `writable<%>`.
> 
> Despite the wordy code and wasting little runtime space, the major problem is 
> all those classes hide their (set-immutable) methods, even worse, the 
> immutability is checked through the private field. As a consequence, 
> subclasses of Pen% and Brush% copy color instances every time to make them 
> immutable (and opaque) again...
> 
> So is it okay to open that interface?
> Besides, With a long term plan, I want to improve the font infrastructure, 
> meanwhile maybe font% also should provide a (get-handler) or (get-desc).
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] [racket][draw] some APIs should be more open

2017-04-11 Thread WarGrey Gyoudmon Ju
This is a little awkward, there are lots of simple classes defined in
racket/draw, font%, color%, pen%, brush% and so on. They just hold a group
of plain data, hence opportunities to be inspected easily. However by
default all classes are opaque, the easiest (and perhaps unique) way to
handle this is to inherit them and implement the `printable<%>` or
`writable<%>`.

Despite the wordy code and wasting little runtime space, the major problem
is all those classes hide their (set-immutable) methods, even worse, the
immutability is checked through the private field. As a consequence,
subclasses of Pen% and Brush% copy color instances every time to make them
immutable (and opaque) again...

So is it okay to open that interface?
Besides, With a long term plan, I want to improve the font infrastructure,
meanwhile maybe font% also should provide a (get-handler) or (get-desc).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.