18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define _USE_MATH_DEFINES 1
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PDFDocumentImage.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CG)
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ImageObserver.h"
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "SharedBuffer.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h>
36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/RetainPtr.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#if !PLATFORM(MAC)
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ImageSourceCG.h"
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPDFDocumentImage::PDFDocumentImage()
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : Image(0) // PDFs don't animate
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_document(0)
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_rotation(0.0f)
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_currentPage(-1)
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPDFDocumentImage::~PDFDocumentImage()
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGPDFDocumentRelease(m_document);
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockString PDFDocumentImage::filenameExtension() const
60dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return "pdf";
62dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIntSize PDFDocumentImage::size() const
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const float sina = sinf(-m_rotation);
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const float cosa = cosf(-m_rotation);
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const float width = m_mediaBox.size().width();
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const float height = m_mediaBox.size().height();
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const float rotWidth = width * cosa - height * sina;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const float rotHeight = width * sina + height * cosa;
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return IntSize((int)(fabsf(rotWidth) + 0.5f), (int)(fabsf(rotHeight) + 0.5f));
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool PDFDocumentImage::dataChanged(bool allDataReceived)
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (allDataReceived && !m_document) {
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(MAC)
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.  We use SharedBuffer's ability
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        RetainPtr<CFDataRef> data(AdoptCF, this->data()->createCFData());
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // Create a CGDataProvider to wrap the SharedBuffer.
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // does not provide a way to lock down the byte pointer and guarantee that it won't move, which
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // is a requirement for using the GetBytePointer callback.
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, 0 };
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateDirect(this->data(), this->data()->size(), &providerCallbacks));
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_document = CGPDFDocumentCreateWithProvider(dataProvider.get());
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setCurrentPage(0);
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_document; // return true if size is available
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PDFDocumentImage::adjustCTM(GraphicsContext* context) const
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // rotate the crop box and calculate bounding box
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float sina = sinf(-m_rotation);
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float cosa = cosf(-m_rotation);
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float width = m_cropBox.width();
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float height = m_cropBox.height();
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // calculate rotated x and y edges of the corp box. if they're negative, it means part of the image has
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // been rotated outside of the bounds and we need to shift over the image so it lies inside the bounds again
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGPoint rx = CGPointMake(width * cosa, width * sina);
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGPoint ry = CGPointMake(-height * sina, height * cosa);
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // adjust so we are at the crop box origin
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const CGFloat zero = 0;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextTranslateCTM(context->platformContext(), floorf(-min(zero, min(rx.x, ry.x))), floorf(-min(zero, min(rx.y, ry.y))));
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // rotate -ve to remove rotation
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextRotateCTM(context->platformContext(), -m_rotation);
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // shift so we are completely within media box
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextTranslateCTM(context->platformContext(), m_mediaBox.x() - m_cropBox.x(), m_mediaBox.y() - m_cropBox.y());
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PDFDocumentImage::setCurrentPage(int page)
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_document)
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (page == m_currentPage)
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!(page >= 0 && page < pageCount()))
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_currentPage = page;
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document, page + 1);
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // get media box (guaranteed)
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox);
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // get crop box (not always there). if not, use media box
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox);
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!CGRectIsEmpty(r))
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_cropBox = r;
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_cropBox = m_mediaBox;
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // get page rotation angle
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_rotation = CGPDFPageGetRotationAngle(cgPage) * piFloat / 180.0f; // to radians
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint PDFDocumentImage::pageCount() const
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_document ? CGPDFDocumentGetNumberOfPages(m_document) : 0;
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
156643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid PDFDocumentImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace, CompositeOperator op)
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_document || m_currentPage == -1)
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context->save();
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context->setCompositeOperation(op);
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float hScale = dstRect.width() / srcRect.width();
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float vScale = dstRect.height() / srcRect.height();
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Scale and translate so the document is rendered in the correct location,
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // including accounting for the fact that a GraphicsContext is always flipped
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and doing appropriate flipping.
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextTranslateCTM(context->platformContext(), dstRect.x() - srcRect.x() * hScale, dstRect.y() - srcRect.y() * vScale);
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextScaleCTM(context->platformContext(), hScale, vScale);
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextScaleCTM(context->platformContext(), 1, -1);
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextTranslateCTM(context->platformContext(), 0, -srcRect.height());
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextClipToRect(context->platformContext(), CGRectIntegral(srcRect));
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Rotate translate image into position according to doc properties.
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    adjustCTM(context);
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextTranslateCTM(context->platformContext(), -m_mediaBox.x(), -m_mediaBox.y());
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextDrawPDFPage(context->platformContext(), CGPDFDocumentGetPage(m_document, m_currentPage + 1));
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context->restore();
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (imageObserver())
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        imageObserver()->didDraw(this);
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif // USE(CG)
192