DirectWrite font rendering.

January 17, 2011

Filed under: HTML and CSS,HTMLayout,Sciter — Andrew @ 8:41 pm

While experimenting with Direct2D/Write back-ends for htmlayout/sciter got these results:

Rendering of <textarea> in default DirectWrite mode:
dw-default
The same but in GDI:
GDI

Probably subjective but classic GDI rendering is better for typical UI font. DirectWrite variant is more blurry (especially note the selection).

So I forced to add one more proprietary CSS property:

font-rendering-mode: classic | enhanced ;

with the default value ‘enhanced’ (that is default DirectWrite mode). So UI developer will be able to tune this up when needed.

Default DirectWrite font rendering mode handles better zooming and rotation situations:
dw-scaled
dw-rotated
(first element uses DirectWrite rendering mode, second – GDI)

Wondering why there are no high-DPI display monitors for desktop use … at least 150 DPI or so …
Tired fighting with graphics anti-aliasing each time to be honest. Last 15 years or so and still no progress :(

Behaviors, simple jQuery extension.

November 14, 2010

Behaviors as an entity is a declarative way to assign/bind scripting methods to DOM elements.

We can think that browsers have following declarations in their default CSS declarations:

input[type=text]   { binding: TextEditorImpl; }
input[type=button] { binding: ButtonImpl; }
select             { binding: SelectImpl; }
...

So when we define <input type="text" /> in our markup we declare that the element will behave as a text editor – it will have set of all needed methods and will generate all associated events.  

It would be nice if in script we would be able to define our own behaviors for classes of DOM elements too.

As an example: blog article may have hyperlinks inside and particular blog engine may require some special behavior/reaction assigned to all hyperlinks in the article. Ideally such declaration should like this:

#content div.article a[href][title]
{
  color: orange; // ui style
  behavior: LinkWithSmartTooltip; // behavioral style
}

In Sciter [1] that is an embeddable HTML/CSS/TIScript engine I have a luxury to step beyond W3C specifications so I’ve implemented the Behaviors in the way as I think they should be:

Behaviors in the Sciter engine

I have added the prototype attribute to my implementation of CSS:

some-CSS-selector
{
   prototype: SomeBehaviorClass [ url(of a script file) ];
   ...
}

When the engine assignes CSS styles to elements it also tries to find class named SomeBehaviorClass. If such class is found then the element gets "subclassed" by the class. Technically the subclassing means that for all DOM elements that satisfy some-CSS-selector both these statements are true:

element instanceof SomeBehaviorClass;
element instanceof Element; // Element is a super class of all DOM elements.

The SomeBehaviorClass looks in TIScript like this:

class SomeBehaviorClass: Behavior
{
   function attached() {} // constructor, sort of
   ...
}

The attached method plays a role of a constructor function in realm of Behaviors. It is called when particular element gets the behavior with this variable referring to the element. All this is I would say is pretty human readable an transparent.

Ok, back to the reality of the Web. Below is my attempt to define similar functionality using jQuery:

Behaviors for conventional browsers,  jQuery extension.

First of all here is my initial implementation of the behavior functionality: jquery-behaviors.js. It is pretty simple – near 75 lines of code.

It allows to declare behaviors on elements by using (a) class DOM attribute like this (purely in markup):

<span class="behavior uix-slider" />
<input class="behavior uix-date" />

and/or by (b) declaration of selector rules in script code:

$.behaviors.selector("ul.ext-list > li", MyExtListItem );

Later case allows to add behaviors non-intrusively – to any existing markup.

The Behaviors implementation above introduces three methods:

  1. $.behaviors.add( name, behaviorObj ) – add named behavior that can be used in "a" case above – in class names.
  2. $.behaviors.selector( selectorStr, behaviorObj ) – add "CSS selector -> behavior" association – case (b) above.
  3. $.fn.behaviors() – that is a plug-in that extends jQuery object wrapping set of elements. It used after calls of DOM mutating methods to assign behaviors to DOM elements:
    $("#update-panel").html("....").behaviors();

The behaviorObj above is the behavior implementation per se. It is a plain JavaScript object that defines set of methods and properties that will be mixed into the DOM element property map.

Here is a typical structure of some behavior named "x-checkbox" (see it’s demo here …) :

$.behaviors.add( "x-checkbox",
{
  $attached: function(params) { ... },
  $value: function(v) { ... },
  $clear: function() { ... }
});

Function $attached here has special meaning – it gets called by the Behaviors engine when the element gets this behavior attached. The params here is a parsed version of the params DOM attribute that allows to parametrize instance of the behavior for the element. For example particular instances of a slider may have different initial settings:

<span id="first" class="behavior uix-slider"
     params="min:0, max:100, values:[15,50]" />
<span id="second" class="behavior uix-slider"
     params="min:10, max:200, value:50" />

Input behaviors, concept of the value. The "x-form" behavior.

In principle there are two distinct types of behaviors:

  • input behaviors – behaviors of elements that have a concept of the value. Input elements have at least these two methods:
    • method $value(v) – getter/setter of the value.
    • method $clear() – clear the value – revert it to the initial, markup declared state.
  • UI behaviors – behaviors implementing various UI effects like "click here – expand/collapse there".

The $value and $clear methods are used by the x-form behavior for gathering and setting values of input elements it contains. The x-form element is by itself is an input element (compound one). Its value is a map of name/value pairs – values of standard inputs and elements that have input behaviors attached. Behavior x-form can be assigned to any container that has inputs and call of its method $("#my-form")[0].$value() will give collection of values that are e.g. ready to be send over the AJAX.

The x-form and individual input behaviors may also implement concept of $validate() – that is not implemented yet but planned.

Demos

Here is couple of demonstrations of the approach:

  • jq-ui.htm – demo of jQuery-UI widgets wrapped into input and UI behaviors (implementation: jquery-ui-behaviors.js).  Also demonstrates use of x-form to gather/set/clear form data and dynamic html loading with behavior assignment.
  • std-behaviors.htm – purely declarative sample. Demonstrates x-checkbox behavior – is a input and UI element that can be bound declaratively with show/hide of "buddy" elements. Uses std-behaviors.js – implementation of the x-form and x-checkbox.

References

  1. The Sciter – an embeddable HTML/CSS/Scripting engine;
  2. TIScript language – JavaScript++ if you wish. Used in Sciter.
  3. Behaviors in Sciter, part I, part II and part III

Style sets in H-SMILE core.

September 27, 2010

Filed under: HTML and CSS,HTMLayout,Sciter — Andrew @ 3:43 pm

HTMLayout and Sciter are both use H-SMILE core to render HTML/CSS. And so both of them support so called style sets.

In this article I’ll try to explain what style set is about and why I decided to introduce them.

First of all: Style set is a named block of style rules – definition of system of style declarations that are applied to some DOM sub-tree.

Style set declaration starts from @style-set at-keyword followed by the name of the style set and block of style rules enclosed in ‘{‘ and ‘}’ brackets:

Code Block A:

@style-set MyStyleSet
{
   :root { font:12pt Verdana; margin:0; padding:0 }
   :root > li { font:12pt Verdana; display:block; }
   strong { color:red; }
}

As we see this style set is named as ‘MyStyleSet’ and contains three rules. Note the use of :root pseudo-class above – inside style set declaration the :root designates element to what this style set is applied. Such an element is a root of DOM sub-tree that uses this style set.

To apply such style set to particular DOM sub-tree we use style-set property in CSS as this:

Code Block B:

ul#my-list
{
   style-set: MyStyleSet;
}

This way we are telling our CSS engine that ul#my-list element and its all sub-elements will use styles from the set above.

Style sets allow to define system of related style declarations in single and compact block. If you have multiple style sets that can be applied to the same sub-tree it is enough to change name of the style set on single element – root element of the sub-tree:

Code Block C:

html[theme="MyCoolTheme"] ul#my-list {  style-set: MyStyleSet; }
html[theme="AnotherCoolTheme"] ul#my-list {  style-set: AnotherStyleSet; }

This way, by changing theme attribute on html element, we can apply two different and independent style sets to ul#my-list element and its children.

Without style sets (in conventional CSS) we will need to write bunch of rules like these:
Code Block D:

html[theme="MyCoolTheme"] ul#my-list { font:12pt Verdana; margin:0; padding:0 }
html[theme="MyCoolTheme"] ul#my-list > li { font:12pt Verdana; display:block; }
html[theme="MyCoolTheme"] ul#my-list strong { color:red; }
html[theme="AnotherCoolTheme"] ul#my-list { font:10pt Arial; margin:0; padding:0 }
html[theme="AnotherCoolTheme"] ul#my-list > li { font:10pt Arial; display:list-item; }
html[theme="AnotherCoolTheme"] ul#my-list strong { color:blue; }

that is not so pretty and quite error prone as any other cut-n-paste approach.

Another benefit of having style set is that they work great in cases when you need to have style libraries. Consider for example jQuery UI library or any other library of Web components. As an example Tabs UI Component may have all its styles defined as a style set:

@style-set Tabs {
   :root > ul.ui-tabs-nav { ... }
   :root > div.ui-tabs-panel { ...; display:none; }
   :root > div.ui-tabs-panel.current { ... ; display:block; }
}

and different theme style files of jQuery UI library might have different and independent declarations of the Tabs style set.

Styles sets are not only convenient and compact way of defining system of styles but they also is a great way to reduce computational complexity of resolving styles of DOM elements. Consider following markup and system of styles defined in Code Block D above:

   <ul id="my-list"><li>Item</li></ul>

To resolve style of the LI element above CSS processor shall scan all rules found in all style sheets (6 of them in this particular example).
For example to determine if this rule:

html[theme="MyCoolTheme"] ul#my-list > li

can be applied to the LI element or not the CSS processor should scan not only the element itself but also all its parents in order to find HTML element with theme attribute set. In general the computational complexity of the style resolution of the DOM having N elements and with S number of style rules is O(N*S).

With style sets the complexity is significantly less because number of styles rules needs to be resolved is less. There are 6 rules in Code Block D (conventional CSS) versus 2 rulers in Code Block C (style sets). Style rules in particular style set will be scanned only for elements that have corresponding style-set property defined.
The style-set property is an inheritable one so any element in sub-tree of “styled root” element will have the same value of the style-set.
In practice this means for example that your UI may have many themes that can be switched in runtime and adding new theme will not slow down style resolution.
You can also create libraries of styles of your components that can be applied to your components by simply defining style-set property in CSS.

More about computational complexity of CSS selectors.

Resolution of styles with style sets of DOM elements

Under the hood resolution of styles is using following steps:

  1. For each particular element styles are getting resolved as usual. Styles inside style-set blocks are not considered at all at this step.
  2. If after step #1 the element gets some value in its style-set property then and only then system is trying to find defined style block. If such block is found then rules from the block are applied on top of properties resolved in step 1 according to specificity of CSS selectors in that style block.

As you see weight of rules defined in style-sets is greater than conventional CSS rules. To override property defined in style set by conventional style rule the later one shall use !important modifier, like this:

ul#my-list
{
   style-set: MyStyleSet;
}
ul#my-list strong
{
   color: yellow !important; /*overriding color set by strong { color:red; } in MyStyleSet */
}

Style sets and OOP

To make style-sets even more modular and reusable I’ve added inheritance in style-sets – you can define new style set that will inherit all rules from the base one.

@style-set Tabs {
   :root > ul.ui-tabs-nav { display: block; margin:Xpx; ... }
   /* all other rules that define layout properties */
}
@style-set BlueTabs < Tabs /* inherits all rules from Tabs set */
{
   :root > ul.ui-tabs-nav { color: blue; }
   /* other "color" rules */
}
@style-set RedTabs < Tabs /* also inherits all rules from Tabs set */
{
   :root > ul.ui-tabs-nav { color: red; }
   /* other "color" rules */
}

The declaration above introduces three style sets that can be used independently and yet RedTabs and BlueTabs use the same shareable prototype – the Tab set.

Style sets are used a lot in so called Master CSS (UA default style sheet) by H-SMILE core engine to give default styling of DOM elements and inputs. Styles sets there allow to minimize time needed for resolution of default styles.

Cheap CSS implementations?

September 2, 2010

Filed under: HTML and CSS — Andrew @ 1:26 pm

CSS3 defines [att=val] selectors . And they work in all modern browsers in static form.

But when you will try to use such a selector with attributes changed from script you will get problems.

Following works as expected in FF but does not work in Google Chrome and Opera:

<html>
<head>
  <style>

    div { display:none; }
    body[show="n1"] #n1 { display:block; }
    body[show="n2"] #n2 { display:block; }

  </style>
  <script type="text/javascript">

    function test()
    {
      document.body.setAttribute("show","n2");
    }

  </script>
</head>
<body show="n1">
  <a href="javascript:test()">Test</a>
  <div id="n1">1</div>
  <div id="n2">2</div>
</body>
</html>

I am wondering why Opera and WebKit implementations are failed on this simple test.
As for my [educated] knowledge attribute value selector has the same complexity as e.g. class selector in CSS. No idea to be honest.

C++, how to change class of object in runtime.

August 12, 2010

Filed under: How-to,Source code — Andrew @ 4:06 pm

There is a nice feature in TIScript that allows to change class of already instantiated object.
Let’s say we have two classes:

class MyWidget : Behavior { ... }
class MyWidgetReadonly : Behavior { ... }

that handle user interaction with some widget on the screen. This widget can operate in two distinct modes: normal and read-only.
These modes share the same widget state but have substantially different behavioral characteristic. So it makes sense to split these two sets of methods into two classes to avoid pollution of our code by the crowd of if(readonly) ... else ....
When needed we can switch class of the object like this:

var widget = new MyWidget();
....
if( needReadOnlyMode )
  widget.prototype = MyWidgetReadonly; // changing class of the object.
...

Pretty much all dynamic languages allow to do such things. E.g. in Python you can modify obj.__bases__.

Surprisingly you can do the same in C++ too and without any “hack”. We can use so called placement new operator to do the trick. Here is how.

Let’s define our class hierarchy as this:

class MyWidget
{
public:
  int data;  // state variables here
  virtual void on_mouse() { printf("normal on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("normal on_key\n"); }
};
class MyWidgetReadOnly: public MyWidget
{
  // no data at all here, sic!
  virtual void on_mouse() { printf("read-only on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("read-only on_key\n"); }
};

And we will switch class of our object using this helper template function:

// turn_to(A* obj) changes class of the object
// that means it just replaces VTBL of the object by VTBL of another class.
// NOTE: these two classes has to be ABI compatible!
template <typename TO_T, typename FROM_T>
  inline void turn_to(FROM_T* p)
  {
    assert( sizeof(FROM_T) == sizeof(TO_T));
    ::new(p) TO_T(); // use of placement new
  }

Note: This will work if our class has default constructor that does not initialize any member variables.

Let’s try this small sample ( test.cpp ):

#include <new>
#include <assert.h>
// turn_to(A* obj) changes class of the object
// that means it just replaces VTBL of the object by VTBL of another class.
// NOTE: these two classes has to be ABI compatible!
template <typename TO_T, typename FROM_T>
  inline void turn_to(FROM_T* p)
  {
    assert( sizeof(FROM_T) == sizeof(TO_T));
    ::new(p) TO_T(); // use of placement new
  }

class MyWidget
{
public:
  int data;  // state variables here
  virtual void on_mouse() { printf("normal on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("normal on_key\n"); }
};
class MyWidgetReadOnly: public MyWidget
{
  // no data at all here, sic!
  virtual void on_mouse() { printf("read-only on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("read-only on_key\n"); }
};

int main(int argc, char* argv[])
{
  MyWidget *w = new MyWidget();
  w->data = 123;
  w->on_mouse();
  turn_to<MyWidgetReadOnly>(w); // turning the instance to MyWidgetReadOnly class.
  w->on_mouse();
	return 0;
}

After compiling and running it we should see in console output like this:

normal on_mouse, data=123
read-only on_mouse, data=123

So it works – we are able to transform existing instance of some class to the instance of other class.

DISCLAIMER:

Be warned that this is a Jedi Sword feature. Use it responsibly, only if you know why you need it. And what are the consequences. Even mentioning of this approach in some software development companies (that usually are on the Dark Side) may damage your reputation.

TIScript: classes, decorators and events.

June 25, 2010

Filed under: Sciter,Script — Andrew @ 7:13 pm

One of differences of TIScript from JavaScript is that it has classes and namespaces.

Declaration of a class in source code looks like this:

class Baz
{
  function foo() { ... }
  property bar(v) { ... }
  // ... other functions, properties, variables,
  // constants and decorator calls ...
}

As you see class declartion in TIScript is pretty similar to the ones in Java or in C++. The only difference is that in TIScript class declaration is an executable (in runtime) entity. While parsing the class declaration above the compiler produces bytecode that is equivalent of this:

const Baz = new Class();
      Baz.foo = function() { .... }
      Baz.bar = property(v) { .... }
...

So while loading bytecodes produced by the compiler TIScript VM will execute sequence of commands to build such class object.

As class construction is an executable chunk of code then in principle we can modify/synthesize class declarations in runtime. And decorators in TIScript are just about this – they allow to execute decorator functions in context of class that is being declared.

Decorator is an ordinary function with the name starting from ‘@’ character. It should have at least one parameter that will receive reference to the object being decorated.

Example of the decorator function, the @returns decorator creates proxy function around call of declarating function and verifies its return value:

function @returns(func, returnType)
{
   return function(params..)
   {
      var r = func.apply(this,params);
      assert typeof r == returnType;
      return r;
   }
}

Having such decorator in place we can declare methods of classes with checks of their return values:

class Zum
{
   @returns #integer
     function Add(i1,i2) {...}
}

The @returns #int function()...  here is a decorator function invocation. Under the hood all this will produce following code:

const Zum = new Class();
      Zum.Add = @returns( function(i1,i2) {...}, #integer );

Call of the @returns() creates proxy for its parameter function. The result (the proxy function) will be assigned to the Add field of the class object. As you may see decorators are pretty much syntax sugar that if properly used may increase expressiveness of your code a lot.

The this environment variable inside the decorator function is getting reference to the context object of the decorator call. E.g. inside class declaration this inside decorator function body will contain reference to the class object.

TIScript supports three types of decorators in total:

  1. Function decorators:  @decorator [...params..] function() { ... }
  2. Class (or namespace) decorators: @decorator [...params..] class { ... }
  3. Empty decorators: @decorator [...params..] ;

Last one – empty decorator – is used in cases when it is a need to synthesize some properties or functions.

Here is practical example of empty decorators used to declare events in class VGrid (Sciter SDK/samples/ideas/virtual-grid/. Virtual Grid is created by Dmitrii Yakimov from http://activekitten.com).

class VGrid: Behavior
{
    const BUF_ROWS = 64;
    ...

   // Events supported by VGrid instances:

   // onCurrentRowChanged( this_grid, row )
   @DECLARE_EVENT #onCurrentRowChanged;

   // onHeaderClick( this_grid, evt, colNo, th )
   @DECLARE_EVENT #onHeaderClick;

   // onCellClick( this_grid, evt, colNo, rowNo, td)
   @DECLARE_EVENT #onCellClick;

   // onRowClick( this_grid, evt, rowNo, tr)
   @DECLARE_EVENT #onRowClick;
}

Each @DECLARE_EVENT eventName; decorator call here creates in the class these three fields:

  • property eventName(v) – that represents list of event handlers assigned to the grid instance by users of the class,
  • function notify_eventName() – function used internally by the class to "raise the event" and
  • var _eventName = [] – variable that holds a list (array) of event handlers (functions) attached to the event by users of the grid.

And here is the implementation of the @DECLARE_EVENT decorator function:

function @DECLARE_EVENT(dummy, eventName)
{
  // create symbols for the fields:
  var notify_sym = symbol( "notify_" + eventName.toString());
  var list_sym = symbol( "_" + eventName.toString());
  var prop_sym = eventName;

  // generate 'notify_' function:
  this[ notify_sym ] = // 'this' here is a class being decorated
    function(params..)
    {
      // 'this' here is VGrid *instance*
      var list = this[list_sym];
      if(typeof list == #array)
      {
        // invoke each function in subscriptions list:
        for( var f in list )
          f.apply(this, this, params); // always pass 'this' in the
                                       // first param - source element
      }
    }
  // adding property  that allows to push
  this[prop_sym] = // 'this' here is a class being decorated,
                   // generating computable property for it.
    property(v)
    {
      get { return this[list_sym] || (this[list_sym] = []); }
      set { throw String.$(Use element.{ list_sym }.push(func)
                                             to subscribe to this event); }
    }
}

The decorator function above is a bit cryptic but defintions like:

@DECLARE_EVENT #onCurrentRowChanged;
@DECLARE_EVENT #onHeaderClick;
...

allow to declare and see the whole event set in compact and convenient form.

« Previous PageNext Page »