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 &layout) (and (set-box! &layout
(pango_cairo_create_layout cr)) (unbox &layout))))
      (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 &ink &logical)

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

      (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 <gneun...@comcast.net>
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
> 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.

Reply via email to