Commit 23b02bc6 authored by Daniel Kochmański's avatar Daniel Kochmański

xx

parent e94fd5d8
......@@ -13,27 +13,31 @@ As programmers, we often deal with the inheritance and the composition,
especially since OOP is a dominating paradigm of programming (no matter if the
central concept is the object or the function). Not so often we deal with the
third type of connection, that is the Form and the phenomena which are merely a
shadow mimicking it[^1].
shadow mimicking it[1].
Let us talk about sheets. The sheet is a region[^2] with an infinite resolution
Let us talk about sheets. The sheet is a region[2] with an infinite resolution
and potentially infinite extent on which we can draw. Sheets may be arranged
into hierarchies creating a windowing system with a child-parent relation. Sheet
is the Form with no visual appearance. What we observe is an approximation of
the sheet which may be hard to recognize when compared to other approximations.
[1]: [Theory of forms](https://en.wikipedia.org/wiki/Theory_of_forms).
[2]: And many other things.
## Physical devices
Sheet hierarchies may be manipulated without a physical medium but to make them
visible we need to draw them. CLIM defines `ports` and `grafts` to allow rooting
sheets to a display server. `medium` is defined to draw sheet approximation on
the screen[^3].
the screen[3].
How should look a square with side length 10 when drawn on a sheet? Since it
doesn't have a unit we can't tell. Before we decide on a unit we choose we need
to take into consideration at least the following scenarios:
1. If we assume device-specific unit results may drastically differ (density may
vary from say 1200dpi on a printer down to 160dpi on a desktop[^4]!. The very
vary from say 1200dpi on a printer down to 160dpi on a desktop[4]!. The very
same square could have 1cm on a paper sheet, 7cm and 10cm on different displays
and 200cm on a terminal. From the perspective of a person who uses the
application, this may be confusing because physical objects don't change size
......@@ -43,7 +47,7 @@ without a reason.
in millimeters (or inches if you must). Thanks to that object will have a
similar size on different mediums. This is better but still not good. We have to
acknowledge that most computer displays are pixel based. Specifying distances in
millimeters will inevitably lead to worse drawing quality[^5] (compared to the
millimeters will inevitably lead to worse drawing quality[5] (compared to the
situation when we use pixels as the base unit). Moreover, conversion from
millimeter values to the pixel will most inevitably lead to work on floats.
......@@ -59,6 +63,11 @@ I will try to answer this question in a moment. First, we have to talk about the
`CLIM` specification and limitations imposed by McCLIM's implementation of
grafts.
[3]: See some [general recommendations](http://bauhh.dyndns.org:8000/clim-spec/12-4.html).
[4]: Technically it should be [PPI, not DPI](https://99designs.com/blog/tips/ppi-vs-dpi-whats-the-difference/) (pixels per inch).
[5]: Given programmer specifies sheet size in integers (like 100x100).
## Ports, grafts, and McCLIM limitations
......@@ -71,7 +80,7 @@ may be perceived depending on its settings and the way we look at it.
As we can see graft has an orientation (`:default` starts at the top-left corner
like a paper sheet and `:graphics` should start at the bottom left corner like
on the chart). Moreover, it has units. Currently, McCLIM will recognize
`:device`, `:inches`, `:millimeters` and `:screen-sized`[^11].
`:device`, `:inches`, `:millimeters` and `:screen-sized`[11].
That said McCLIM doesn't implement graft in a useful way. Everything is measured
in pixels (which `:device` units are assumed to be) and only the `:default`
......@@ -79,6 +88,9 @@ orientation is implemented. By now we should already know that pixels are a not
a good choice for the default unit. Also, programmer doesn't have means to
request unit for a sheet (this is the API problem).
[11]: Screen size unit means that the coordinate [1/2, 1/2] is exactly in the
middle of the screens.
## Physical size and pixel size compromise
We will skip the third situation, for now, to decide what unit should we default
......@@ -92,11 +104,12 @@ be
[device-independent pixel](https://en.wikipedia.org/wiki/Device-independent_pixel).
One of McCLIM long-term goals is to adhere
to [Material Design](https://material.io/) guidelines – that's why we will use
dip[^6] unit. 100dp has absolute value 15.875mm. On 160dpi display it is 100px,
dip[6] unit. 100dp has absolute value 15.875mm. On 160dpi display it is 100px,
on 96dpi display it is 60px, on 240dpi display it is 150px etc. This unit gives
us some nice characteristics: we are rather compatible with the existing
applications and we preserving absolute distances across different screens.
[6]: [Density-independent pixel](https://material.io/guidelines/layout/units-measurements.html#units-measurements-density-independent-pixels-dp).
## How to draw a rectangle on the medium
......@@ -106,7 +119,7 @@ which have absolute value 0.15875mm. It is the McCLIM responsibility to map
these units onto the device. To be precise each graft needs to hold an extra
transformation which is applied before sending content to the display server.
Now we will go through a few example mappings of two rectangle borders[^7] drawn
Now we will go through a few example mappings of two rectangle borders[7] drawn
on a sheet. The violet rectangle coordinates are `[5,5], [22,35]` and the cyan
rectangle coordinates are `[25,10], [30,15]`.
......@@ -116,7 +129,7 @@ rectangle coordinates are `[25,10], [30,15]`.
![Graft drawing](https://common-lisp.net/project/mcclim/static/media/ideal-forms/mdpi.png)
* Some old displays have density 72PPI. Not all coordinates map exactly to
pixels - we need to round them[^3]. Notice that border is thicker and that
pixels - we need to round them[3]. Notice that border is thicker and that
proportions are a little distorted. On the other hand despite a big change in
resolution size of the object is similar in real-world values.
......@@ -173,13 +186,16 @@ important to know where we start the drawing.
![80DPI and MDPI plotters](https://common-lisp.net/project/mcclim/static/media/ideal-forms/plotters.png)
[7]: the Ideal border is composed of lines which are 1-dimensional objects
which doesn't occupy any space. Red border in drawings marks "ideal" object
boundaries. Points are labeled in device units (with possible fractions).
## Sheets written with a special device in mind
There is still an unanswered question - how can we program applications with a
specific device limitations in mind? As we have discussed earlier default sheet
unit should be dip and default sheet orientation is the same as a paper
sheet's[^8].
sheet's[8].
Writing an application for a terminal is different than writing an application
for a web browser. The number of characters which fit on the screen is limited,
......@@ -191,7 +207,7 @@ characters. Take a look at the following example.
The first sheet base unit is a character of a certain physical size. We print
some information on it in various colors. Nothing prevents us from drawing a
circle[^9] but that would miss the point. We use a character as a unit because
circle[9] but that would miss the point. We use a character as a unit because
we don't want rounding and approximation. Background and foreground colors are
inherited.
......@@ -213,6 +229,12 @@ The second screen is mDPI display. The second sheet looks very much like
something we have defined. What is more interesting though is our first sheet –
it looks exactly the same as on the terminal.
[8]: Providing means to change defaults requires additional thought and is a
material for a separate chapter. McCLIM doesn't allow it yet.
[9]: As we have noted sheets are ideal planar spaces where line thickness is 0
and there is nothing preventing us from using fractions as coordinates.
<!-- Writing applications for terminal require a special kind of focus: space is -->
<!-- very limited and off-by-one errors yield a huge difference in visual appearance in -->
<!-- the application. Rounding from dip is a big no for some use cases. On the other -->
......@@ -240,7 +262,7 @@ remind you what kind of objects we are dealing with:
* Port is a logical connection to a display server. For instance, it may contain
a foreign handler which is passed to the external system API. It is
responsible for the communication – configuring, writing to and reading[^10]
responsible for the communication – configuring, writing to and reading[10]
from a device, we are connected to.
* Graft is a logical screen representation on which we draw. It is responsible
......@@ -257,31 +279,5 @@ of the medium) for the charming backend. I will cover only bare minimum for
mediums important to verify that graft works as expected. Complete medium
implementation is the material for a separate post.
[^1]: [Theory of forms](https://en.wikipedia.org/wiki/Theory_of_forms).
[^2]: And many other things.
[^3]: See some [general recommendations](http://bauhh.dyndns.org:8000/clim-spec/12-4.html).
[^4]: Technically it should be [PPI, not DPI](https://99designs.com/blog/tips/ppi-vs-dpi-whats-the-difference/) (pixels per inch).
[^5]: Given programmer specifies sheet size in integers (like 100x100).
[^6]: [Density-independent pixel](https://material.io/guidelines/layout/units-measurements.html#units-measurements-density-independent-pixels-dp).
[^7]: the Ideal border is composed of lines which are 1-dimensional objects
which doesn't occupy any space. Red border in drawings marks "ideal" object
boundaries. Points are labeled in device units (with possible fractions).
[^8]: Providing means to change defaults requires additional thought and is a
material for a separate chapter. McCLIM doesn't allow it yet.
[^9]: As we have noted sheets are ideal planar spaces where line thickness is 0
and there is nothing preventing us from using fractions as coordinates.
[^10]: Sometimes we deal with devices which we can't take input from – for
[10]: Sometimes we deal with devices which we can't take input from – for
instance a printer, a PDF render or a display without other peripherals.
[^11]: Screen size unit means that the coordinate [1/2, 1/2] is exactly in the
middle of the screens.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment