Changeset 155069 in webkit
- Timestamp:
- Sep 4, 2013 3:08:26 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r155067 r155069 1 2013-09-04 Tim Horton <timothy_horton@apple.com> 2 3 [mac] PDFDocumentImage should use PDFKit to draw 4 https://bugs.webkit.org/show_bug.cgi?id=120651 5 <rdar://problem/12810731> 6 7 Reviewed by Alexey Proskuryakov. 8 9 * fast/images/pdf-as-image-with-annotations-expected.html: Added. 10 * fast/images/pdf-as-image-with-annotations.html: Added. 11 * fast/images/resources/annotation.pdf: Added. 12 Add a test that ensures that PDF-in-<img> draws simple annotations. 13 14 * platform/mac/fast/images/pdf-as-image-landscape-expected.png: 15 * platform/mac/fast/images/pdf-as-image-landscape-expected.txt: 16 Extremely minor rebaselines probably due to PDFKit handling rotation in the new implementation. 17 1 18 2013-09-04 Ryosuke Niwa <rniwa@webkit.org> 2 19 -
trunk/LayoutTests/platform/mac/fast/images/pdf-as-image-landscape-expected.txt
r73385 r155069 1 layer at (0,0) size 850x65 31 layer at (0,0) size 850x654 2 2 RenderView at (0,0) size 785x585 3 layer at (0,0) size 785x65 34 RenderBlock {HTML} at (0,0) size 785x65 35 RenderBody {BODY} at (8,8) size 769x6 293 layer at (0,0) size 785x654 4 RenderBlock {HTML} at (0,0) size 785x654 5 RenderBody {BODY} at (8,8) size 769x630 6 6 RenderBlock (anonymous) at (0,0) size 769x18 7 7 RenderText {#text} at (0,0) size 663x18 8 8 text run at (0,0) width 349: "This test that we correctly orient landscape pdf images. " 9 9 text run at (349,0) width 314: "The green rectangle should be wider than it is tall." 10 RenderBlock {P} at (0,34) size 769x59 511 RenderImage {IMG} at (0,0) size 842x59 510 RenderBlock {P} at (0,34) size 769x596 11 RenderImage {IMG} at (0,0) size 842x596 12 12 RenderText {#text} at (0,0) size 0x0 -
trunk/Source/WebCore/ChangeLog
r155068 r155069 1 2013-09-04 Tim Horton <timothy_horton@apple.com> 2 3 [mac] PDFDocumentImage should use PDFKit to draw 4 https://bugs.webkit.org/show_bug.cgi?id=120651 5 <rdar://problem/12810731> 6 7 Reviewed by Alexey Proskuryakov. 8 9 Use PDFKit to draw PDF-in-<img> on Mac, so that annotations in PDF are painted. 10 11 Test: fast/images/pdf-as-image-with-annotations.html 12 13 * WebCore.xcodeproj/project.pbxproj: 14 Add PDFDocumentImageMac.mm. 15 16 * platform/graphics/cg/PDFDocumentImage.cpp: 17 (WebCore::PDFDocumentImage::PDFDocumentImage): 18 We don't need to initialize m_document anymore because it's now a RetainPtr. 19 Initialize m_hasPage to false. 20 21 (WebCore::PDFDocumentImage::~PDFDocumentImage): 22 We don't need to manually release our CGPDFDocumentRef anymore because it's now a RetainPtr. 23 24 (WebCore::PDFDocumentImage::size): 25 Use expandedIntSize for explicitness. 26 27 (WebCore::PDFDocumentImage::applyRotationForPainting): 28 Rename adjustCTM to applyRotationForPainting, and move the one non-rotation related transformation out. 29 We need to do this because PDFKit applies the rotation transformation itself, so we don't need to. 30 Also, explicitly use std::min instead of importing the whole std namespace. 31 32 (WebCore::PDFDocumentImage::dataChanged): 33 Assert that we don't re-enter dataChanged after we've created a document, 34 because it seems like that shouldn't happen - we only create a document when 35 we've supposedly received all data, and it would be nice if we didn't have 36 all this varying code to deal with SharedBuffers changing out from under each other. 37 Factor the code to create a CGPDFDocumentRef out into createPDFDocument, so we can 38 replace it with a different implementation that creates a PDFDocument. 39 40 (WebCore::PDFDocumentImage::setCurrentPage): 41 Make all page-number-related things unsigned, since they are in CG and PDFKit, 42 and add m_hasPage to denote whether we've acquired a valid page yet. 43 Factor code to retrieve the PDF box bounds into computeBoundsForCurrentPage. 44 Remove setCurrentPage itself, as we never use a page other than the first page; 45 we will call computeBoundsForCurrentPage and set hasPage in dataChanged, now. 46 47 (WebCore::PDFDocumentImage::draw): 48 Fix a weird comment. 49 Factor code that actually draws the PDF out into drawPDFPage. 50 51 The rest of the functions in this file are only built for USE(CG) && !PLATFORM(MAC): 52 53 (WebCore::PDFDocumentImage::createPDFDocument): 54 Factored out of dataChanged(); I only kept the !PLATFORM(MAC) branch. 55 56 (WebCore::PDFDocumentImage::computeBoundsForCurrentPage): 57 Factored out of setCurrentPage(). 58 Use deg2rad since we have it. 59 60 (WebCore::PDFDocumentImage::pageCount): 61 (WebCore::PDFDocumentImage::drawPDFPage): 62 Factored out of draw(). 63 Reduced an unnecessary transform (we were effectively doing mediaBox.origin - cropBox.origin - mediaBox.origin). 64 65 * platform/graphics/cg/PDFDocumentImage.h: 66 Unindent all the things, as we don't indent the first level inside a namespace scope. 67 Forward-declare PDFDocument. 68 Make m_currentPage unsigned as it should be. 69 Add m_hasPage. 70 Make m_document a PDFDocument on PLATFORM(MAC) and a CGPDFDocumentRef on other platforms. 71 72 * platform/graphics/mac/PDFDocumentImageMac.mm: Added. 73 Soft-link in PDFKit and specifically the PDFDocument class. 74 75 (WebCore::PDFDocumentImage::createPDFDocument): 76 Create our PDFDocument from the SharedBuffer's NSData directly. This shouldn't be a problem 77 (with respect to the SharedBuffer's data being appended to in secret), because we've waited 78 for the document to finish loading before getting here. 79 80 (WebCore::PDFDocumentImage::computeBoundsForCurrentPage): 81 Ask PDFKit for the page's media and crop boxes; it automatically performs the correct fallback. 82 Ask PDFKit for the page's rotation. 83 84 (WebCore::PDFDocumentImage::pageCount): 85 Ask PDFKit for the page count. 86 87 (WebCore::PDFDocumentImage::drawPDFPage): 88 Paint the current page of the PDF. Note that we do not apply the rotation here 89 via applyRotationForPainting because PDFKit will do it itself. 90 91 * platform/mac/SoftLinking.h: 92 I couldn't find any clients of SOFT_LINK_FRAMEWORK_IN_CORESERVICES_UMBRELLA, 93 so I made it the more generic SOFT_LINK_FRAMEWORK_IN_UMBRELLA, taking the name 94 of the umbrella framework and the subframework, so I could use it to soft link 95 Quartz.framework's PDFKit.framework. 96 1 97 2013-09-04 Roger Fong <roger_fong@apple.com> 2 98 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r155057 r155069 905 905 2D5A5931152525D00036EE51 /* ImageOrientation.h in Headers */ = {isa = PBXBuildFile; fileRef = A8748D6612CC3763001FBA41 /* ImageOrientation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 906 906 2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5BC42516F882BE007048D0 /* SecurityPolicyViolationEvent.h */; }; 907 2D6E468417D660F500ECF8BB /* PDFDocumentImageMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D6E468217D660F500ECF8BB /* PDFDocumentImageMac.mm */; }; 907 908 2D8287F616E4A0380086BD00 /* HitTestLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D8287F416E4A0380086BD00 /* HitTestLocation.cpp */; }; 908 909 2D8287F716E4A0380086BD00 /* HitTestLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D8287F516E4A0380086BD00 /* HitTestLocation.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 7344 7345 2D5BC42516F882BE007048D0 /* SecurityPolicyViolationEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecurityPolicyViolationEvent.h; sourceTree = "<group>"; }; 7345 7346 2D5BC42616F882BE007048D0 /* SecurityPolicyViolationEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SecurityPolicyViolationEvent.idl; sourceTree = "<group>"; }; 7347 2D6E468217D660F500ECF8BB /* PDFDocumentImageMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PDFDocumentImageMac.mm; sourceTree = "<group>"; }; 7346 7348 2D8287F416E4A0380086BD00 /* HitTestLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HitTestLocation.cpp; sourceTree = "<group>"; }; 7347 7349 2D8287F516E4A0380086BD00 /* HitTestLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HitTestLocation.h; sourceTree = "<group>"; }; … … 18717 18719 E4B41E110CBF90EF00AF2ECE /* MediaPlayerPrivateQTKit.mm */, 18718 18720 0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */, 18721 2D6E468217D660F500ECF8BB /* PDFDocumentImageMac.mm */, 18719 18722 163E88F5118A39D200ED9231 /* SimpleFontDataCoreText.cpp */, 18720 18723 B2AFFC770D00A5C10030074D /* SimpleFontDataMac.mm */, … … 25992 25995 C5137CF211A58378004ADB99 /* JSDOMStringList.cpp in Sources */, 25993 25996 9A1B6F97158869C80011A8C4 /* JSDOMStringListCustom.cpp in Sources */, 25997 2D6E468417D660F500ECF8BB /* PDFDocumentImageMac.mm in Sources */, 25994 25998 BC64649711D82349006455B0 /* JSDOMStringMap.cpp in Sources */, 25995 25999 BC64649C11D8238C006455B0 /* JSDOMStringMapCustom.cpp in Sources */, -
trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
r149255 r155069 1 1 /* 2 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved.2 * Copyright (C) 2004, 2005, 2006, 2013 Apple Computer, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 43 43 #endif 44 44 45 using namespace std;46 47 45 namespace WebCore { 48 46 49 47 PDFDocumentImage::PDFDocumentImage() 50 48 : Image(0) // PDFs don't animate 51 , m_document(0)52 49 , m_rotation(0.0f) 53 , m_ currentPage(-1)50 , m_hasPage(false) 54 51 { 55 52 } … … 57 54 PDFDocumentImage::~PDFDocumentImage() 58 55 { 59 CGPDFDocumentRelease(m_document);60 56 } 61 57 … … 71 67 const float width = m_mediaBox.size().width(); 72 68 const float height = m_mediaBox.size().height(); 73 const float rotWidth = width * cosa - height * sina;74 const float rotHeight = width * sina + height * cosa;69 const float rotWidth = fabsf(width * cosa - height * sina); 70 const float rotHeight = fabsf(width * sina + height * cosa); 75 71 76 return IntSize((int)(fabsf(rotWidth) + 0.5f), (int)(fabsf(rotHeight) + 0.5f));72 return expandedIntSize(FloatSize(rotWidth, rotHeight)); 77 73 } 78 74 … … 86 82 bool PDFDocumentImage::dataChanged(bool allDataReceived) 87 83 { 84 ASSERT(!m_document); 88 85 if (allDataReceived && !m_document) { 89 #if PLATFORM(MAC) 90 // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge. We use SharedBuffer's ability 91 // to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer. 92 RetainPtr<CFDataRef> data = adoptCF(this->data()->createCFData()); 93 RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateWithCFData(data.get())); 94 #else 95 // Create a CGDataProvider to wrap the SharedBuffer. 96 // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer 97 // does not provide a way to lock down the byte pointer and guarantee that it won't move, which 98 // is a requirement for using the GetBytePointer callback. 99 CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, 0 }; 100 RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateDirect(this->data(), this->data()->size(), &providerCallbacks)); 101 #endif 102 m_document = CGPDFDocumentCreateWithProvider(dataProvider.get()); 103 setCurrentPage(0); 86 createPDFDocument(); 87 88 if (pageCount()) { 89 m_hasPage = true; 90 computeBoundsForCurrentPage(); 91 } 104 92 } 105 return m_document; // return true if size is available93 return m_document; // Return true if size is available. 106 94 } 107 95 108 void PDFDocumentImage::a djustCTM(GraphicsContext* context) const96 void PDFDocumentImage::applyRotationForPainting(GraphicsContext* context) const 109 97 { 110 98 // rotate the crop box and calculate bounding box … … 114 102 float height = m_cropBox.height(); 115 103 116 // calculate rotated x and y edges of the c orp box. if they're negative, it means part of the image has104 // calculate rotated x and y edges of the crop box. if they're negative, it means part of the image has 117 105 // been rotated outside of the bounds and we need to shift over the image so it lies inside the bounds again 118 106 CGPoint rx = CGPointMake(width * cosa, width * sina); … … 121 109 // adjust so we are at the crop box origin 122 110 const CGFloat zero = 0; 123 CGContextTranslateCTM(context->platformContext(), floorf(- min(zero, min(rx.x, ry.x))), floorf(-min(zero,min(rx.y, ry.y))));111 CGContextTranslateCTM(context->platformContext(), floorf(-std::min(zero, std::min(rx.x, ry.x))), floorf(-std::min(zero, std::min(rx.y, ry.y)))); 124 112 125 113 // rotate -ve to remove rotation 126 114 CGContextRotateCTM(context->platformContext(), -m_rotation); 127 128 // shift so we are completely within media box129 CGContextTranslateCTM(context->platformContext(), m_mediaBox.x() - m_cropBox.x(), m_mediaBox.y() - m_cropBox.y());130 }131 132 void PDFDocumentImage::setCurrentPage(int page)133 {134 if (!m_document)135 return;136 137 if (page == m_currentPage)138 return;139 140 if (!(page >= 0 && page < pageCount()))141 return;142 143 m_currentPage = page;144 145 CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document, page + 1);146 147 // get media box (guaranteed)148 m_mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox);149 150 // get crop box (not always there). if not, use media box151 CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox);152 if (!CGRectIsEmpty(r))153 m_cropBox = r;154 else155 m_cropBox = m_mediaBox;156 157 // get page rotation angle158 m_rotation = CGPDFPageGetRotationAngle(cgPage) * piFloat / 180.0f; // to radians159 }160 161 int PDFDocumentImage::pageCount() const162 {163 return m_document ? CGPDFDocumentGetNumberOfPages(m_document) : 0;164 115 } 165 116 166 117 void PDFDocumentImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace, CompositeOperator op, BlendMode) 167 118 { 168 if (!m_document || m_currentPage == -1)119 if (!m_document || !m_hasPage) 169 120 return; 170 121 … … 178 129 179 130 // Scale and translate so the document is rendered in the correct location, 180 // including accounting for the fact that a GraphicsContext is always flipped 181 // and doing appropriate flipping. 131 // accounting for the fact that the GraphicsContext is flipped. 182 132 CGContextTranslateCTM(context->platformContext(), dstRect.x() - srcRect.x() * hScale, dstRect.y() - srcRect.y() * vScale); 183 133 CGContextScaleCTM(context->platformContext(), hScale, vScale); … … 186 136 CGContextClipToRect(context->platformContext(), CGRectIntegral(srcRect)); 187 137 188 // Rotate translate image into position according to doc properties. 189 adjustCTM(context); 190 191 CGContextTranslateCTM(context->platformContext(), -m_mediaBox.x(), -m_mediaBox.y()); 192 CGContextDrawPDFPage(context->platformContext(), CGPDFDocumentGetPage(m_document, m_currentPage + 1)); 138 drawPDFPage(context); 193 139 } 194 140 … … 197 143 } 198 144 145 #if !USE(PDFKIT_FOR_PDFDOCUMENTIMAGE) 146 void PDFDocumentImage::createPDFDocument() 147 { 148 // Create a CGDataProvider to wrap the SharedBuffer. 149 // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer 150 // does not provide a way to lock down the byte pointer and guarantee that it won't move, which 151 // is a requirement for using the GetBytePointer callback. 152 153 CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, 0 }; 154 RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateDirect(this->data(), this->data()->size(), &providerCallbacks)); 155 m_document = CGPDFDocumentCreateWithProvider(dataProvider.get()); 156 } 157 158 void PDFDocumentImage::computeBoundsForCurrentPage() 159 { 160 CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document.get(), 1); 161 162 m_mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox); 163 164 // Get crop box (not always there). If not, use media box. 165 CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox); 166 if (!CGRectIsEmpty(r)) 167 m_cropBox = r; 168 else 169 m_cropBox = m_mediaBox; 170 171 m_rotation = deg2rad(static_cast<float>(CGPDFPageGetRotationAngle(cgPage))); 172 } 173 174 unsigned PDFDocumentImage::pageCount() const 175 { 176 return CGPDFDocumentGetNumberOfPages(m_document.get()); 177 } 178 179 void PDFDocumentImage::drawPDFPage(GraphicsContext* context) 180 { 181 applyRotationForPainting(context); 182 183 CGContextTranslateCTM(context->platformContext(), -m_cropBox.x(), -m_cropBox.y()); 184 185 // CGPDF pages are indexed from 1. 186 CGContextDrawPDFPage(context->platformContext(), CGPDFDocumentGetPage(m_document.get(), 1)); 187 } 188 #endif // !USE(PDFKIT_FOR_PDFDOCUMENTIMAGE) 189 199 190 } 200 191 -
trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h
r141637 r155069 1 1 /* 2 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved.2 * Copyright (C) 2004, 2005, 2006, 2013 Apple Computer, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 33 33 #if USE(CG) 34 34 35 #if PLATFORM(MAC) && !PLATFORM(IOS) 36 #define WTF_USE_PDFKIT_FOR_PDFDOCUMENTIMAGE 1 37 #endif 38 35 39 typedef struct CGPDFDocument *CGPDFDocumentRef; 40 OBJC_CLASS PDFDocument; 36 41 37 42 namespace WebCore { 38 43 39 44 class GraphicsContext; 40 45 41 42 43 44 45 46 46 class PDFDocumentImage : public Image { 47 public: 48 static PassRefPtr<PDFDocumentImage> create() 49 { 50 return adoptRef(new PDFDocumentImage); 51 } 47 52 48 private: 49 virtual ~PDFDocumentImage(); 53 private: 54 PDFDocumentImage(); 55 virtual ~PDFDocumentImage(); 50 56 51 virtual String filenameExtension() const;57 virtual String filenameExtension() const OVERRIDE; 52 58 53 virtual bool hasSingleSecurityOrigin() const{ return true; }59 virtual bool hasSingleSecurityOrigin() const OVERRIDE { return true; } 54 60 55 virtual bool dataChanged(bool allDataReceived);61 virtual bool dataChanged(bool allDataReceived) OVERRIDE; 56 62 57 58 59 virtual void destroyDecodedData(bool /*destroyAll*/ = true){ }60 virtual unsigned decodedSize() const{ return 0; }63 // FIXME: PDF Images are underreporting decoded sizes and will be unable 64 // to prune because these functions are not implemented yet. 65 virtual void destroyDecodedData(bool /*destroyAll*/ = true) OVERRIDE { } 66 virtual unsigned decodedSize() const OVERRIDE { return 0; } 61 67 62 virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio);63 virtual IntSize size() const;68 virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) OVERRIDE; 69 virtual IntSize size() const OVERRIDE; 64 70 65 PDFDocumentImage(); 66 virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator, BlendMode); 71 virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator, BlendMode) OVERRIDE; 67 72 68 69 73 // FIXME: Implement this to be less conservative. 74 virtual bool currentFrameKnownToBeOpaque() OVERRIDE { return false; } 70 75 71 void setCurrentPage(int); 72 int pageCount() const; 73 void adjustCTM(GraphicsContext*) const; 76 void applyRotationForPainting(GraphicsContext*) const; 74 77 75 CGPDFDocumentRef m_document; 76 FloatRect m_mediaBox; 77 FloatRect m_cropBox; 78 float m_rotation; 79 int m_currentPage; 80 }; 78 void createPDFDocument(); 79 void computeBoundsForCurrentPage(); 80 unsigned pageCount() const; 81 void drawPDFPage(GraphicsContext*); 82 83 #if USE(PDFKIT_FOR_PDFDOCUMENTIMAGE) 84 RetainPtr<PDFDocument> m_document; 85 #else 86 RetainPtr<CGPDFDocumentRef> m_document; 87 #endif 88 89 FloatRect m_mediaBox; 90 FloatRect m_cropBox; 91 float m_rotation; 92 bool m_hasPage; 93 }; 81 94 82 95 } -
trunk/Source/WebCore/platform/mac/SoftLinking.h
r152571 r155069 66 66 } 67 67 68 #define SOFT_LINK_FRAMEWORK_IN_ CORESERVICES_UMBRELLA(framework) \68 #define SOFT_LINK_FRAMEWORK_IN_UMBRELLA(umbrella, framework) \ 69 69 static void* framework##Library() \ 70 70 { \ 71 static void* frameworkLibrary = dlopen("/System/Library/Frameworks/ CoreServices.framework/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \71 static void* frameworkLibrary = dlopen("/System/Library/Frameworks/" #umbrella ".framework/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \ 72 72 ASSERT_WITH_MESSAGE(frameworkLibrary, "%s", dlerror()); \ 73 73 return frameworkLibrary; \
Note: See TracChangeset
for help on using the changeset viewer.