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