diff options
author | Feng Qian <> | 2009-04-10 18:11:29 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-10 18:11:29 -0700 |
commit | 8f72e70a9fd78eec56623b3a62e68f16b7b27e28 (patch) | |
tree | 181bf9a400c30a1bf34ea6d72560e8d00111d549 /WebCore/platform/graphics/chromium/TransparencyWin.h | |
parent | 7ed56f225e0ade046e1c2178977f72b2d896f196 (diff) | |
download | external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.zip external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.gz external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.bz2 |
AI 145796: Land the WebKit merge @r42026.
Automated import of CL 145796
Diffstat (limited to 'WebCore/platform/graphics/chromium/TransparencyWin.h')
-rw-r--r-- | WebCore/platform/graphics/chromium/TransparencyWin.h | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/WebCore/platform/graphics/chromium/TransparencyWin.h b/WebCore/platform/graphics/chromium/TransparencyWin.h new file mode 100644 index 0000000..e1963b3 --- /dev/null +++ b/WebCore/platform/graphics/chromium/TransparencyWin.h @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TransparencyWin_h +#define TransparencyWin_h + +#include <windows.h> + +#include "ImageBuffer.h" +#include "Noncopyable.h" +#include "TransformationMatrix.h" +#include "wtf/OwnPtr.h" + +class SkBitmap; +class SkCanvas; + +namespace WebCore { + +class GraphicsContext; +class TransparencyWin_NoLayer_Test; +class TransparencyWin_WhiteLayer_Test; +class TransparencyWin_TextComposite_Test; +class TransparencyWin_OpaqueCompositeLayer_Test; + +// Helper class that abstracts away drawing ClearType text and Windows form +// controls either to the original context directly, or to an offscreen context +// that is composited later manually. This is to get around Windows' inability +// to handle the alpha channel, semitransparent text, and transformed form +// controls. +class TransparencyWin : public Noncopyable { +public: + enum LayerMode { + // No extra layer is created. Drawing will happen to the source. + // Valid only with KeepTransform and ScaleTransform. The region being + // drawn onto must be opaque, since the modified region will be forced + // to opaque when drawing is complete. + NoLayer, + + // Makes a temporary layer consisting of the composited layers below + // it. This result must be opaque. When complete, the result will be + // compared to the original, and the difference will be added to a thee + // destination layer. + // + // This mode only works if the lower layers are opque (normally the + // case for a web page) and layers are only drawn in the stack order, + // meaning you can never draw underneath a layer. + // + // This doesn't technically produce the correct answer in all cases. If + // you have an opaque base, a transparency layer, than a semitransparent + // drawing on top, the result will actually be blended in twice. But + // this isn't a very important case. This mode is used for form + // controls which are always opaque except for occationally some + // antialiasing. It means form control antialiasing will be too light in + // some cases, but only if you have extra layers. + OpaqueCompositeLayer, + + // Allows semitransparent text to be drawn on any background (even if it + // is itself semitransparent), but disables ClearType. + // + // It makes a trmporary layer filled with white. This is composited with + // the lower layer with a custom color applied to produce the result. + // The caller must draw the text in black, and set the desired final + // text color by calling setTextCompositeColor(). + // + // Only valid with KeepTransform, which is the only mode where drawing + // text in this fashion makes sense. + TextComposite, + + // Makes a temporary layer filled with white. When complete, the layer + // will be forced to be opqaue (since Windows may have messed up the + // alpha channel) and composited down. Any areas not drawn into will + // remain white. + // + // This is the mode of last resort. If the opacity of the final image + // is unknown and we can't do the text trick (since we know its color), + // then we have to live with potential white halos. This is used for + // form control drawing, for example. + WhiteLayer, + }; + + enum TransformMode { + // There are no changes to the transform. Use this when drawing + // horizontal text. The current transform must not have rotation. + KeepTransform, + + // Drawing happens in an Untransformed space, and then that bitmap is + // transformed according to the current context when it is copied down. + // Requires that a layer be created (layer mode is not NoLayer). + Untransform, + + // When the current transform only has a scaling factor applied and + // you're drawing form elements, use this parameter. This will unscale + // the coordinate space, so the OS will just draw the form controls + // larger or smaller depending on the destination size. + ScaleTransform, + }; + + // You MUST call init() below. + // |region| is expressed relative to the current transformation. + TransparencyWin(); + ~TransparencyWin(); + + // Initializes the members if you use the 0-argument constructor. Don't call + // this if you use the multiple-argument constructor. + void init(GraphicsContext* dest, + LayerMode layerMode, + TransformMode transformMode, + const IntRect& region); + + // Combines the source and destination bitmaps using the given mode. + void composite(); + + // Returns the context for drawing into, which may be the destination + // context, or a temporary one. + GraphicsContext* context() const { return m_drawContext; } + + PlatformGraphicsContext* platformContext() const { return m_drawContext->platformContext(); } + + // When the mode is TextComposite, this sets the color that the text will + // get. See the enum above for more. + void setTextCompositeColor(Color color); + + // Returns the input bounds translated into the destination space. This is + // not necessary for KeepTransform since the rectangle will be unchanged. + const IntRect& drawRect() { return m_drawRect; } + +private: + friend TransparencyWin_NoLayer_Test; + friend TransparencyWin_WhiteLayer_Test; + friend TransparencyWin_TextComposite_Test; + friend TransparencyWin_OpaqueCompositeLayer_Test; + + class OwnedBuffers; + + void computeLayerSize(); + + // Sets up a new layer, if any. setupLayer() will call the appopriate layer- + // specific helper. Must be called after computeLayerSize(); + void setupLayer(); + void setupLayerForNoLayer(); + void setupLayerForOpaqueCompositeLayer(); + void setupLayerForTextComposite(); + void setupLayerForWhiteLayer(); + + // Sets up the transformation on the newly created layer. setupTransform() + // will call the appropriate transform-specific helper. Must be called after + // setupLayer(). + void setupTransform(const IntRect& region); + void setupTransformForKeepTransform(const IntRect& region); + void setupTransformForUntransform(); + void setupTransformForScaleTransform(); + + void initializeNewContext(); + + void compositeOpaqueComposite(); + void compositeTextComposite(); + + // Fixes the alpha channel to make the region inside m_transformedRect + // opaque. + void makeLayerOpaque(); + + // The context our drawing will eventually end up in. + GraphicsContext* m_destContext; + + // The original transform from the destination context. + TransformationMatrix m_orgTransform; + + LayerMode m_layerMode; + TransformMode m_transformMode; + + // The rectangle we're drawing in the destination's coordinate space + IntRect m_sourceRect; + + // The source rectangle transformed into pixels in the final image. For + // Untransform this has no meaning, since the destination might not be a + // rectangle. + IntRect m_transformedSourceRect; + + // The size of the layer we created. If there's no layer, this is the size + // of the region we're using in the source. + IntSize m_layerSize; + + // The rectangle we're drawing to in the draw context's coordinate space. + // This will be the same as the source rectangle except for ScaleTransform + // where we create a new virtual coordinate space for the layer. + IntRect m_drawRect; + + // Points to the graphics context to draw text to, which will either be + // the original context or the copy, depending on our mode. + GraphicsContext* m_drawContext; + + // This flag is set when we call save() on the draw context during + // initialization. It allows us to avoid doing an extra save()/restore() + // when one is unnecessary. + bool m_savedOnDrawContext; + + // Used only when m_mode = TextComposite, this is the color that the text + // will end up being once we figure out the transparency. + Color m_textCompositeColor; + + // Layer we're drawing to. + ImageBuffer* m_layerBuffer; + + // When the layer type is OpaqueCompositeLayer, this will contain a copy + // of the original contents of the m_layerBuffer before Windows drew on it. + // It allows us to re-create what Windows did to the layer. It is an + // SkBitmap instead of an ImageBuffer because an SkBitmap is lighter-weight + // (ImageBuffers are also GDI surfaces, which we don't need here). + SkBitmap* m_referenceBitmap; + + // If the given size of bitmap can be cached, they will be stored here. Both + // the bitmap and the reference are guaranteed to be allocated if this + // member is non-null. + static OwnedBuffers* m_cachedBuffers; + + // If a buffer was too big to be cached, it will be created temporarily, and + // this member tracks its scope to make sure it gets deleted. Always use + // m_layerBuffer, which will either point to this object, or the statically + // cached one. Don't access directly. + OwnPtr<OwnedBuffers> m_ownedBuffers; +}; + +} // namespace WebCore + +#endif // TransaprencyWin_h |