Rasterize: Resolution option not working properly

With a bit of spelunking I extracted the following from

g = Graphics[{Circle[], FontSize -> 20, Text["x^2+y^2<1", {0, 0}]}, ImageSize -> 72];
Trace[Rasterize[g, ImageSize -> 72, ImageResolution -> 100]]

in v.10.0.1.


An excerpt from the Trace output

1) At first, the value of RasterSize is extracted from the Rasterize command using OptionValue:

System`ConvertersDump`rs$ = 
 OptionValue[Rasterize, {ImageSize -> 72, ImageResolution -> 100}, RasterSize]
Automatic

2) In our case RasterSize is Automatic (the default value) and hence on the following line the value of ImageSize option (which has dimensionality of printer's points, i.e. the base unit is inch) is incorrectly taken as RasterSize (which has dimensionality of pixels) without taking into consideration ImageResolution:

If[System`ConvertersDump`rs$ === Automatic, 
      System`ConvertersDump`rs$ = 
        OptionValue[Rasterize, {ImageSize -> 72, ImageResolution -> 100}, 
         ImageSize]]
72

3) Now the new value for RasterSize is converted into the form {width, heigh}:

If[! ListQ[System`ConvertersDump`rs$] || Length[System`ConvertersDump`rs$] != 2, 
 System`ConvertersDump`rs$ = {System`ConvertersDump`rs$, Automatic}]
{72, Automatic}

4) At the next step final image resolution is calculated from the new RasterSize (note that the original ImageResolution is present but ignored!):

{System`ConvertersDump`w$, System`ConvertersDump`h$} = System`ConvertersDump`rs$;

System`ConvertersDump`ir$ = 
     System`ConvertersDump`GetIR[
      Graphics[{Circle[{0, 0}], FontSize -> 20, Text["x^2+y^2<1", {0, 0}]}, ImageSize -> 72], 
       {System`ConvertersDump`w$, System`ConvertersDump`h$}, 
           ImageSize -> 72, ImageResolution -> 100]
72

5) And finally the packet is constructed using the obtained value for ImageResolution:

System`ConvertersDump`rdpdata$ = 
     System`ConvertersDump`ToRasterDataPacket[
       Graphics[{Circle[{0, 0}], FontSize -> 20, Text["x^2+y^2<1", {0, 0}]}, ImageSize -> 72], 
       {"Rasterize", "BoundingBox"}, 
       ImageResolution -> System`ConvertersDump`ir$, Background -> System`ConvertersDump`bg$, 
       ColorSpace -> System`ConvertersDump`cs$, 
       Sequence @@ 
         FilterRules[{ImageSize -> 72, ImageResolution -> 100}, 
         Except[{ImageResolution, Background, ColorSpace}]]]

What happens when ImageSize is not specified

When ImageSize is not specified, everything is the same up to the step 4):

System`ConvertersDump`ir$ = 
     System`ConvertersDump`GetIR[
      Graphics[{Circle[{0, 0}], FontSize -> 20, Text["x^2+y^2<1", {0, 0}]}, ImageSize -> 72], 
       {System`ConvertersDump`w$, System`ConvertersDump`h$}, 
           ImageResolution -> 100]
100

We see that when the new value of RasterSize is {Automatic, Automatic} the original value of ImageResolution is taken as the final value for image resolution at this step.


Conclusion

From the above it is clear that the key option which currently determines the image resolution in Rasterize is not ImageResolution but RasterSize.

The mechanism of the inconsistent behavior described in the question is as follows: when non-Automatic ImageSize is specified without RasterSize it is taken as ImageResolution. This contradicts to the documented meaning of these options: ImageSize specifies the size of the image in printer's points where inch is the base unit while ImageResolution has dimensionality of dots per inch.

At the same time the combination RasterSize + ImageSize works as expected in accord with the Documentation. So the workaround is to use RasterSize and do not rely on ImageResolution.


I don't have time for a complete answer at the moment but hopefully this helps. I believe that ImageSize, if specified directly inside Rasterize, overrides the ImageResolution. Observe this behavior when ImageSize is used in Graphics instead:

g = Graphics[{Circle[], FontSize -> 20, Text["x^2+y^2<1", {0, 0}]}, ImageSize -> 130];

r = Table[Rasterize[g, "Image", ImageResolution -> r], {r, {20, 40, 100}}]

enter image description here


An examination of ImageSize

Since my original post Alexey Popkov provided a much deeper analysis but pragmatically the conclusion is the same: when ImageSize is given as an option of Rasterize it overrides ImageResolution, but when ImageSize is given as part of a Graphics expression ImageResolution has effect.

A question remains as to the intended (or desired) behavior in this case. Alexey correctly notes that ImageSize is ostensibly defined in printer's points:

d                         d printer's points (before magnification)

However I find this to be practically false. If you specify an ImageSize of 100 you get an image that is 100 pixels wide. This equivalence requires a resolution of 72 pixels per inch (assuming PostScript printer's points). This resolution is highly outdated as modern displays different resolutions that are often much higher.

Mathematica is aware of the OS-specified resolution. For example under Windows 7 I have "Medium" selected which sets the OS to 120ppi and Mathematica knows this:

CurrentValue["ScreenResolution"]
{120, 120}

Nevertheless the Front End ignores this resolution and renders my ImageSize -> 100 graphic as 100 pixels wide rather than 167 pixels wide as it would if ImageSize really meant printer's point and not pixels. Further there is a System Option for screen resolution and it too is ignored:

enter image description here

This setting has no effect that I have observed on ImageSize rendering.

There is the setting "ScreenResolution" under "FontProperties" that does have effect but only on font size. Observe this example where FontSize -> 20 is correctly rendered at different specified resolutions:

Graphics[{"FontProperties" -> {"ScreenResolution" -> #}, Circle[], FontSize -> 20, 
    Text["x^2+y^2<1", {0, 0}]}, ImageSize -> 130] & /@ {30, 60, 100}

enter image description here

I must conclude that by convention and the documentation notwithstanding ImageSize is in actuality specified in pixel dimension, not printer's points, as far as the Front End is concerned.

Therefore it is entirely reasonable that if an absolute ImageSize is given to Rasterize it will use this value rather than one derived from ImageResolution. I therefore further conclude that this behavior is not a bug. However the entire disregarding of screen resolution by the Front End and the effective specification of ImageSize in pixels might be.