HTML-Renderer icon indicating copy to clipboard operation
HTML-Renderer copied to clipboard

Images are not scaled

Open PeterWone opened this issue 6 years ago • 1 comments

Specifying height and width for images works correctly only when the unit is px.

PeterWone avatar May 13 '19 01:05 PeterWone

Oh where to begin...

  1. There's missing behaviour in public static void MeasureImageSize in CssLayoutEngine.cs which handles px and percentage and just doesn't bother with anything else.
  2. Centimetre and millimetre are spelt incorrectly in the enumeration. This isn't vital but it's conspicuous when you write the missing cases with a switch statement.
  3. Everything assumes 96dpi. Research reveals that CSS requires print devices to scale px to 1/96" which makes this a less crazy decision.
  4. There's no way to get the dpi of the device context to which you're rendering. This is probably why everything assumes 96dpi -- that and print scaling.
  5. Integration of SVG handling was thwarted by the fact that the code depends on ImageFromStream for decoding. This can only handle bitmaps (PNG, JPG etc).

At least in the callback I have direct access to the Graphics object so I can obtain the rendering resolution.

I solved all the absolute scaling problems but didn't handle Em or Ex because it wasn't obvious how to get the font size of the container.

Here's the crux of the fix

      else if (imageWord.Image != null)
      {
        switch (height.Unit)
        {
          case CssUnit.Picas:
            imageWord.Height = height.Number * 96.0 / 6.0;
            break;
          case CssUnit.Pixels:
            imageWord.Height = height.Number;
            break;
          case CssUnit.Points:
            imageWord.Height = height.Number * 96.0 / 72.0;
            break;
          case CssUnit.Inches:
            imageWord.Height = height.Number * 96.0;
            break;
          case CssUnit.Centimetres:
            imageWord.Height = height.Number * 96.0 / 2.54;
            break;
          case CssUnit.Millimetres:
            imageWord.Height = height.Number * 96.0 / 25.4;
            break;
          default:
            imageWord.Height = imageWord.ImageRectangle == RRect.Empty ? imageWord.Image.Height : imageWord.ImageRectangle.Height;
            break;
        }
      }

Obviously you have to do the same for width.

If I get a chance to sort out font relative units I may offer a PR.

PeterWone avatar May 17 '19 04:05 PeterWone