Women in Technology

Hear us Roar



Subject:   macos x already works like this
Date:   2004-03-22 12:32:11
From:   mweiher
Response to: macos x already works like this

1. "That title bar is not in vector format - it's three bitmaps"


This turns out not to be the case. While you are correct that I did look at it in Preview, I also went to the trouble of actually dumping out the PDF drawing stream.


While there are some bitmaps used, the main part of the title bar is a rectangle (vectors) that is filled with a pattern. It is *not* a bitmap.


This is the dump of the actual page content stream:



"q Q q 181 466.5 12 22 re W n 0 sc /Gs1 gs 181 466.5 12 22 re f /Perceptual
ri /Gs2 gs q 24 0 0 22 181 466.5 cm /Im1 Do Q Q q 649 466.5 12 22 re
W n 0 sc /Gs1 gs 649 466.5 12 22 re f /Perceptual ri /Gs2 gs q 24 0
0 22 637 466.5 cm /Im2 Do Q Q q 193 466.5 456 22 re W n /Pattern cs
/P1 scn 193 466.5 456 22 re f
Q q 394 469.5 54 17 re W n 1 1 1 0 k
q 1 0 0 -1 394 486.5 cm BT 13 0 0 -13 2 14 Tm /F1.0 1 Tf (Window) Tj
ET Q Q q 181 106.5 480 382 re W n /Pattern cs /P2 scn 181 106.5 480
360 re f Q q 189 468.5 14 16 re W n /Perceptual ri q 14 0 0 16 189
468.5 cm /Im3 Do Q Q q 231 468.5 14 16 re W n /Perceptual ri q 14 0
0 16 231 468.5 cm /Im4 Do Q Q q 210 468.5 14 16 re W n /Perceptual
ri q 14 0 0 16 210 468.5 cm /Im5 Do Q Q q 181 106.5 480 382 re W n
/Perceptual ri q 15 0 0 15 646 106.5 cm /Im6 Do Q Q"


The crucial part is the following bit:



/Pattern cs /P1 scn 193 466.5 456 22 re f


This sets up a pattern color-space, then draws a rectangle that is filled with this pattern.


The pattern that is used is defined as follows:



q Q q /Perceptual ri /Im7 Do Q


So here we get the "bitmap" that Illustrator seems to pick up. But this is not a bitmap that is drawn, it is a bitmap pattern that is used as a fill-color for a rectangle. This bitmap is a 24 x 22 vertical gradient from 0xfe to 0x9d.


So why are we seeing a shape filled with a pattern that is a bitmap? Simple: a "bitmap" of gradually changing values is actually the recommended method for drawing a linear gradient in PDF! Or more precisely, was until version 1.3 of the spec. introduced shading dictionaries.


Because we are using a well defined and device-independent imaging model, we know that drawing an image with the 256 gray values 0-255 is exactly the same as drawing 256 rectangles with gray values ranging from 0.0 - 1.0 (if we set up the color-spaces correctly). This can then be scaled to the required dimensions.


So what you are seeing is a gradient implemented in PDF, at 24 step "resolution". Which, incidentally, is completely equivalent to drawing 24 (vector) rectangles, not just practically but also theoretically! Now they could have used more steps to define the gradient, but that would have been pretty pointless given the fact that this is a window title bar. They could also have used a shading dictionary, but that is only available in newer PDF versions, and my guess is that it just wasn't needed.


2. "Scaling failure" with NSImageView


You have made a well-known beginner's mistake in using NSImage that dates back to NextStep days. If you look up the NSImge documentation, you will find that it creates and caches a device-specific rendered version of any resource it uses. And it will then throw away the original, unless it is told otherwise. This behavior is appropriate for the NSImage's intended use: drawing icons and other screen ornaments.


I am guessing you set up your NSImageView completely within Interface Builder, including referencing the pdf "image" by name from within the nib. That is how you get the behavior you describe, and I have duplicated this behavior in the following PDF example:


NonScalable.pdf


As you have noted, even that example will "scale" with the window as you change size, because the NSImage notices that its cached representation is not at the appropriate resolution for the current scale and will thus generate a new representation that does have the appropriate resolution for that particular scale.


If you don't want that behavior, just use - (void)setDataRetained:(BOOL)flag to tell it to retain the original, which it will automatically do if initialized with a file path (instead of an image name, for exmaple). So, to get perfectly scalable output, just make the NSImageView "Editable" (there's a check box in Interface Builder) and drop a pdf in at runtime. I actually took the exact same PDF that I was referencing from within the nib and dropped it in the image-view. Voilá, perfectly scalable output, because the original scalable representation is retained:


Scalable.pdf


In fact, you can use the same pdf both time. Incidentally, the reason that the output did appear scalable while you were resizing is that NSImage will automagically notice that the scale it is drawing at to screen has changed and go back to the original source to re-render a cached representation for that scale. So as you can see, all the machinery is already in place, and WORKING, for automatic adjustment to different resolutions.


Of course, invoking -setDataRetained: is timing-sensitive, there is no use doing this after the NSImage has already discarded the original.


So to sum up: both of your "proofs" have evaporated, as usual, and just show that you didn't know what you're doing on Mac OS X. Of course, not knowing what you're doing on the Mac is OK, you're a Windows programmer after all. However, it is usually better to avoid making bold assertions by drawing wrong conclusions from an incomplete and flawed understanding of the facts.

Full Threads Newest First

Showing messages 1 through 1 of 1.

  • Ian Griffiths photo macos x already works like this
    2004-07-01 06:13:41  Ian Griffiths | O'Reilly Author [View]

    "But this is not a bitmap that is drawn, it is a bitmap pattern that is used as a fill-color for a rectangle."

    You're splitting hairs here. It's only "not a bitmap" if you use a narrow definition of "bitmap" that exludeds "bitmap patterns". But this is a dicussion about scalability, and bitmap patterns aren't any more scalable than non-bitmap patterns, so there's no significant difference between the two - 'bitmaps' and 'bitmap patterns' are just two ways of painting with bitmap imagery.

    In other words, it's still a bitmap, even if it's in pattern form. Indeed it's a 24x22 bitmap, according to your analysis, which is not scalable - the pixellation is quite obvious when you enlarge it, and that is my point. You previously claimed that it was perfectly smooth and scalable, but now you're agreeing that it is essentially bitmap data. (And yes, it's a bitmap pattern - it's still a bitmap-like image source; the fact that it's being used as a fill pattern rather than a standalone image doesn't change its intrinsic non-scalability.)

    So all I was saying is that it doesn't make your argument look very credible when you produce what you have now admitted is a 24x22 bitmap pattern, but claim that it is "smoothly scalable". This is emphatically not compelling evidence for the allegedly scalable nature you are claiming Quartz 2D has.

    Bitmaps may be the standard way of hacking up graduated fills in PDF, but they're just that - a hack. If you use a 16 bit per channel colour space, then 256 rectangles is not a proper representation of a graduated fill. (Also, drawing 256 rectangles is emphatically *not* the same things as a bitmap with 256 pixels - you have a widely-held but wrong-headed view of what a bitmap represents. This is, as you put it, a rookie mistake. I won't reproduce the argument here, because you can find an excellent explanation of why you're wrong if you google for "A pixel is not a little square") And in any case your argument doesn't even stand up on its own: you've not got 256 levels here - only 24. Which is not enough, and here's that word again, to make it *scalable* - it looks wrong when you enlarge it. The pixellation is clearly visible.



    "You have made a well-known beginner's mistake in using NSImage"

    No doubt - I am after all not experienced with OS X. But why on earth would it behave this way? This just shows that by default, OS X applications are not necessarily resolution independent, even if they use resolution independent image sources.

    If this is, as you say, a well-known mistake, doubtless that means loads of people have made it. (Particularly since this mistake causes absolutely no problems on screen that I can see - it behaves absolutely correctly when the application is running at the native screen resolution. In fact for on-screen use, the term 'mistake' doesn't seem applicable - there's nothing wrong with the application's behaviour. Problems only start to occur when we attempt to get a scalable version of the display.) Does that mean that every application that makes this mistake is going to look crummy if Apple ever get around to supporting high resolution displays?

    This all add weight to my argument that OS X is, by default, not scalable. If a perfectly straightforward way of putting vector imagery into A UI turns out not to be resolution independent, then OS X is not intrinsically resolution independent, end of story.

    It remains *possible* to write resolution-independent apps. But you have to set out to do that. It won't happen by accident. The same has been true in Windows for a decade now.



    "So to sum up: both of your "proofs" have evaporated,"

    What proofs? I was just pointing out that the image you supplied was not what you claimed it to be. And apparently I was right - you have now admitted that the fill is in fact a bitmap pattern. (That may be the standard way of doing grad fills, but it doesn't change the fact that it is, according to your analysis, a 22x24 bitmap pattern, which is not a scalable way of creating an image.)

    My assertion is, and has always been, that OS X is just like Windows today - it's a platform you can build resolution-independent UIs with if you make the effort, but in which UIs will typically not be resolution by default, because it requires effort to achieve resolution independence.

    I may have blundered into these proofs, but that doesn't change the basic facts. I, as a beginner, wrote an application that works absolutely fine in the native resolution, but turns out not to be resolution indepent. This proves point: resolution independence is not automatic in OS X.

    That's the point I've been putting to you all along, and you've been denying all along. All it took was a rookie mistake to proove the point... :-)

    The fact that I blundered into this existence proof doesn't reduce its worth. You seem to be attempting to dismiss me because I don't know a lot about OS X. That's a falacious argument, and I think you know it is. I can tell that, say, the elements of the button in the PDF I produced don't line up properly at all resolutions without having to be an expert Mac developer. Remember, you started generating PDFs as a way of trying to prove your point - I'm just using my non-technology-specific ability to recognize cruddy imagery when I see it to point out that these PDFs seem to be demonstrating the opposite of what you claim.

    (Unless of course creating PDFs like this was just the wrong way to go about things. Maybe that's a facility that doesn't really work right anyway. In which case, all these sample PDFs don't really proove anything at all.)



    Meanwhile, I see you've quietly ignored the other problem I illustrated in my example - that the button looks terrible. In fact it looks wrong even at the natural resolution, and just looks worse as you scale it.

    Actually I'll go into a little more detail on the button, because I didn't mention the most interesting thing about it. Try a few different magnifications. Notice how sometimes, the middle section lines up with the caps, and sometimes it doesn't. This is typical of the problems you will see if you try to scale the output of a program that has never been tested at any resolution other than its native resolution.

    This is one of the two main reasons why Apple can't simply apply a scale factor of 1.5 to applications running on a 150dpi display - lots of little glitches like that will come crawling out of the woodwork. In other words, it's pretty much exactly the same reason Microsoft don't do the very same thing on Windows. (The second reason is the widespread reliance on bitmaps in most UIs.)

    In fact it wouldn't surprise me if this problem - the fact that a scalable drawing API turns out not to be as useful as you might thing for making scalable UIs - is the whole reason they have decided to 'solve' the problem by arbtrarily declaring recently that 100dpi is the perfect resolution. This to me looks like a positive spin on an admission of defeat that they can't solve the scalability problem with the technology they have today. (Surely nobody actually *believes* that 100dpi is the ideal resolution. Are Apple going to recommend we throw out our 600dpi laser printers and dig out those old dot matrix machines?)

    Or did I make a rookie mistake with the button too?