static CFDictionaryRef createImageSourceOptions(ImageSource::ShouldSkipMetadata skipMetaData, SubsamplingLevel subsamplingLevel) { const CFBooleanRef imageSourceSkipMetadata = (skipMetaData == ImageSource::SkipMetadata) ? kCFBooleanTrue : kCFBooleanFalse; if (!subsamplingLevel) { const unsigned numOptions = 3; const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetadata }; const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, imageSourceSkipMetadata }; return CFDictionaryCreate(nullptr, keys, values, numOptions, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } short constrainedSubsamplingLevel = std::min<short>(3, std::max<short>(0, subsamplingLevel)); int subsampleInt = 1 << constrainedSubsamplingLevel; // [0..3] => [1, 2, 4, 8] RetainPtr<CFNumberRef> subsampleNumber = adoptCF(CFNumberCreate(nullptr, kCFNumberIntType, &subsampleInt)); const CFIndex numOptions = 4; const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetadata, kCGImageSourceSubsampleFactor }; const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, imageSourceSkipMetadata, subsampleNumber.get() }; return CFDictionaryCreate(nullptr, keys, values, numOptions, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); }
static RetainPtr<CFDictionaryRef> createPropertyListRepresentationFromResource(ArchiveResource* resource, bool mainResource) { if (!resource) { // The property list representation of a null/empty WebResource has the following 3 objects stored as nil RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 3, 0, 0)); CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceDataKey, 0); CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceURLKey, 0); CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceMIMETypeKey, 0); return propertyList; } RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 6, 0, &kCFTypeDictionaryValueCallBacks)); // Resource data can be empty, but must be represented by an empty CFDataRef SharedBuffer* data = resource->data(); RetainPtr<CFDataRef> cfData; if (data) cfData.adoptCF(data->createCFData()); else cfData.adoptCF(CFDataCreate(0, 0, 0)); CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceDataKey, cfData.get()); // Resource URL cannot be null RetainPtr<CFStringRef> cfURL(AdoptCF, resource->url().string().createCFString()); if (cfURL) CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceURLKey, cfURL.get()); else { LOG(Archives, "LegacyWebArchive - NULL resource URL is invalid - returning null property list"); return 0; } // FrameName should be left out if empty for subresources, but always included for main resources const String& frameName(resource->frameName()); if (!frameName.isEmpty() || mainResource) { RetainPtr<CFStringRef> cfFrameName(AdoptCF, frameName.createCFString()); CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceFrameNameKey, cfFrameName.get()); } // Set MIMEType, TextEncodingName, and ResourceResponse only if they actually exist const String& mimeType(resource->mimeType()); if (!mimeType.isEmpty()) { RetainPtr<CFStringRef> cfMIMEType(AdoptCF, mimeType.createCFString()); CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceMIMETypeKey, cfMIMEType.get()); } const String& textEncoding(resource->textEncoding()); if (!textEncoding.isEmpty()) { RetainPtr<CFStringRef> cfTextEncoding(AdoptCF, textEncoding.createCFString()); CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceTextEncodingNameKey, cfTextEncoding.get()); } // Don't include the resource response for the main resource if (!mainResource) { RetainPtr<CFDataRef> resourceResponseData = propertyListDataFromResourceResponse(resource->response()); if (resourceResponseData) CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceResponseKey, resourceResponseData.get()); } return propertyList; }
bool decodeResourceResponse(ArgumentDecoder* decoder, WebCore::ResourceResponse& resourceResponse) { #if USE(CFNETWORK) bool responseIsPresent; if (!decoder->decode(responseIsPresent)) return false; if (!responseIsPresent) { resourceResponse = WebCore::ResourceResponse(); return true; } RetainPtr<CFDictionaryRef> dictionary; if (!decode(decoder, dictionary)) return false; CFURLResponseRef cfURLResponse = wkCFURLResponseCreateFromSerializableRepresentation(dictionary.get(), CoreIPC::tokenNullTypeRef()); if (!cfURLResponse) return false; resourceResponse = WebCore::ResourceResponse(cfURLResponse); return true; #else return false; #endif }
void TestRunner::setPersistentUserStyleSheetLocation(JSStringRef jsURL) { RetainPtr<CFStringRef> urlString = adoptCF(JSStringCopyCFString(0, jsURL)); ::setPersistentUserStyleSheetLocation(urlString.get()); }
void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& point) { // FIXME: Creating CFData is non-optimal, but needed to avoid crashing when printing. Ideally we should // make a custom CGDataProvider that controls the WindowsBitmap lifetime. see <rdar://6394455> RetainPtr<CFDataRef> imageData = adoptCF(CFDataCreate(kCFAllocatorDefault, image->buffer(), image->bufferLength())); RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateWithCFData(imageData.get())); RetainPtr<CGImageRef> cgImage = adoptCF(CGImageCreate(image->size().width(), image->size().height(), 8, 32, image->bytesPerRow(), deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little | kCGImageAlphaFirst, dataProvider.get(), 0, true, kCGRenderingIntentDefault)); CGContextDrawImage(m_data->m_cgContext.get(), CGRectMake(point.x(), point.y(), image->size().width(), image->size().height()), cgImage.get()); }
String contextMenuItemTagSearchWeb() { #if PLATFORM(COCOA) RetainPtr<CFStringRef> searchProviderName = adoptCF(wkCopyDefaultSearchProviderDisplayName()); return formatLocalizedString(WEB_UI_STRING("Search with %@", "Search with search provider context menu item with provider name inserted"), searchProviderName.get()); #else return WEB_UI_STRING("Search with Google", "Search with Google context menu item"); #endif }
static void convertWebResourceResponseToDictionary(CFMutableDictionaryRef propertyList) { CFDataRef responseData = static_cast<CFDataRef>(CFDictionaryGetValue(propertyList, CFSTR("WebResourceResponse"))); // WebResourceResponseKey in WebResource.m if (CFGetTypeID(responseData) != CFDataGetTypeID()) return; RetainPtr<CFURLResponseRef> response = adoptCF(createCFURLResponseFromResponseData(responseData)); if (!response) return; RetainPtr<CFMutableDictionaryRef> responseDictionary = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); RetainPtr<CFMutableStringRef> urlString = adoptCF(CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFURLGetString(CFURLResponseGetURL(response.get())))); normalizeWebResourceURL(urlString.get()); CFDictionarySetValue(responseDictionary.get(), CFSTR("URL"), urlString.get()); RetainPtr<CFMutableStringRef> mimeTypeString = adoptCF(CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFURLResponseGetMIMEType(response.get()))); convertMIMEType(mimeTypeString.get()); CFDictionarySetValue(responseDictionary.get(), CFSTR("MIMEType"), mimeTypeString.get()); CFStringRef textEncodingName = CFURLResponseGetTextEncodingName(response.get()); if (textEncodingName) CFDictionarySetValue(responseDictionary.get(), CFSTR("textEncodingName"), textEncodingName); SInt64 expectedContentLength = CFURLResponseGetExpectedContentLength(response.get()); RetainPtr<CFNumberRef> expectedContentLengthNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &expectedContentLength)); CFDictionarySetValue(responseDictionary.get(), CFSTR("expectedContentLength"), expectedContentLengthNumber.get()); if (CFHTTPMessageRef httpMessage = CFURLResponseGetHTTPResponse(response.get())) { RetainPtr<CFDictionaryRef> allHeaders = adoptCF(CFHTTPMessageCopyAllHeaderFields(httpMessage)); RetainPtr<CFMutableDictionaryRef> allHeaderFields = adoptCF(CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, allHeaders.get())); normalizeHTTPResponseHeaderFields(allHeaderFields.get()); CFDictionarySetValue(responseDictionary.get(), CFSTR("allHeaderFields"), allHeaderFields.get()); CFIndex statusCode = CFHTTPMessageGetResponseStatusCode(httpMessage); RetainPtr<CFNumberRef> statusCodeNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &statusCode)); CFDictionarySetValue(responseDictionary.get(), CFSTR("statusCode"), statusCodeNumber.get()); } CFDictionarySetValue(propertyList, CFSTR("WebResourceResponse"), responseDictionary.get()); }
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) { ASSERT_ARG(buffer, buffer); #if USE(OPENTYPE_SANITIZER) OpenTypeSanitizer sanitizer(buffer); RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize(); if (!transcodeBuffer) return 0; // validation failed. buffer = transcodeBuffer.get(); #else RefPtr<SharedBuffer> sfntBuffer; if (isWOFF(buffer)) { Vector<char> sfnt; if (!convertWOFFToSfnt(buffer, sfnt)) return 0; sfntBuffer = SharedBuffer::adoptVector(sfnt); buffer = sfntBuffer.get(); } #endif ATSFontContainerRef containerRef = 0; RetainPtr<CGFontRef> cgFontRef; #ifndef BUILDING_ON_LEOPARD RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData()); RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get())); cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get())); if (!cgFontRef) return 0; #else // Use ATS to activate the font. // The value "3" means that the font is private and can't be seen by anyone else. ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef); if (!containerRef) return 0; ItemCount fontCount; ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount); // We just support the first font in the list. if (fontCount == 0) { ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); return 0; } ATSFontRef fontRef = 0; ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL); if (!fontRef) { ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); return 0; } cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef)); // Workaround for <rdar://problem/5675504>. if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get())) cgFontRef = 0; if (!cgFontRef) { ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); return 0; } #endif // !defined(BUILDING_ON_LEOPARD) FontCustomPlatformData* fontCustomPlatformData = new FontCustomPlatformData(containerRef, cgFontRef.releaseRef()); #if USE(SKIA_ON_MAC_CHROMIUM) RemoteFontStream* stream = new RemoteFontStream(buffer); fontCustomPlatformData->m_typeface = SkTypeface::CreateFromStream(stream); stream->unref(); #endif return fontCustomPlatformData; }
ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, ColorSpace imageColorSpace, RenderingMode renderingMode, DeferralMode, bool& success) : m_data(size) // NOTE: The input here isn't important as ImageBufferDataCG's constructor just ignores it. , m_logicalSize(size) , m_resolutionScale(resolutionScale) { float scaledWidth = ceilf(resolutionScale * size.width()); float scaledHeight = ceilf(resolutionScale * size.height()); // FIXME: Should we automatically use a lower resolution? if (!FloatSize(scaledWidth, scaledHeight).isExpressibleAsIntSize()) return; m_size = IntSize(scaledWidth, scaledHeight); success = false; // Make early return mean failure. bool accelerateRendering = renderingMode == Accelerated; if (m_size.width() <= 0 || m_size.height() <= 0) return; Checked<int, RecordOverflow> width = m_size.width(); Checked<int, RecordOverflow> height = m_size.height(); // Prevent integer overflows m_data.m_bytesPerRow = 4 * width; Checked<size_t, RecordOverflow> numBytes = height * m_data.m_bytesPerRow; if (numBytes.hasOverflowed()) return; #if USE(IOSURFACE_CANVAS_BACKING_STORE) if (width.unsafeGet() >= maxIOSurfaceDimension || height.unsafeGet() >= maxIOSurfaceDimension || (width * height).unsafeGet() < minIOSurfaceArea) accelerateRendering = false; #else ASSERT(renderingMode == Unaccelerated); #endif switch (imageColorSpace) { case ColorSpaceDeviceRGB: m_data.m_colorSpace = deviceRGBColorSpaceRef(); break; case ColorSpaceSRGB: m_data.m_colorSpace = sRGBColorSpaceRef(); break; case ColorSpaceLinearRGB: m_data.m_colorSpace = linearRGBColorSpaceRef(); break; } RetainPtr<CGContextRef> cgContext; if (accelerateRendering) { #if USE(IOSURFACE_CANVAS_BACKING_STORE) m_data.m_surface = createIOSurface(m_size); cgContext.adoptCF(wkIOSurfaceContextCreate(m_data.m_surface.get(), width.unsafeGet(), height.unsafeGet(), m_data.m_colorSpace)); #endif if (!cgContext) accelerateRendering = false; // If allocation fails, fall back to non-accelerated path. } if (!accelerateRendering) { if (!tryFastCalloc(height.unsafeGet(), m_data.m_bytesPerRow.unsafeGet()).getValue(m_data.m_data)) return; ASSERT(!(reinterpret_cast<size_t>(m_data.m_data) & 2)); m_data.m_bitmapInfo = kCGImageAlphaPremultipliedLast; cgContext.adoptCF(CGBitmapContextCreate(m_data.m_data, width.unsafeGet(), height.unsafeGet(), 8, m_data.m_bytesPerRow.unsafeGet(), m_data.m_colorSpace, m_data.m_bitmapInfo)); // Create a live image that wraps the data. m_data.m_dataProvider.adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, numBytes.unsafeGet(), releaseImageData)); } if (!cgContext) return; m_context = adoptPtr(new GraphicsContext(cgContext.get())); m_context->applyDeviceScaleFactor(m_resolutionScale); m_context->scale(FloatSize(1, -1)); m_context->translate(0, -size.height()); m_context->setIsAcceleratedContext(accelerateRendering); #if defined(BUILDING_ON_LION) m_data.m_lastFlushTime = currentTimeMS(); #endif success = true; }
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) { ASSERT_ARG(buffer, buffer); #if ENABLE(OPENTYPE_SANITIZER) OpenTypeSanitizer sanitizer(buffer); RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize(); if (!transcodeBuffer) return 0; // validation failed. buffer = transcodeBuffer.get(); #endif ATSFontContainerRef containerRef = 0; ATSFontRef fontRef = 0; RetainPtr<CGFontRef> cgFontRef; #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData()); RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get())); cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get())); if (!cgFontRef) return 0; #else // Use ATS to activate the font. // The value "3" means that the font is private and can't be seen by anyone else. ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef); if (!containerRef) return 0; ItemCount fontCount; ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount); // We just support the first font in the list. if (fontCount == 0) { ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); return 0; } ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL); if (!fontRef) { ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); return 0; } cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef)); #ifndef BUILDING_ON_TIGER // Workaround for <rdar://problem/5675504>. if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get())) cgFontRef = 0; #endif #if PLATFORM(APOLLO) // On Leopard the CGFontGetNumberOfGlyphs call is necessary to reject invalid fonts // On Snow Leopard this happens at ATSFontActivateFromMemory if (isOsLeopardOrGreater()) { static _CGFontGetNumberOfGlyphsFunc CGFontGetNumberOfGlyphsFunc = getCGFontGetNumberOfGlyphsFunc(); if (CGFontGetNumberOfGlyphsFunc && cgFontRef && !CGFontGetNumberOfGlyphsFunc(cgFontRef.get())) { cgFontRef = 0; } } #endif if (!cgFontRef) { ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); return 0; } #endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) return new FontCustomPlatformData(containerRef, fontRef, cgFontRef.releaseRef()); }
bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const Font* fontData) { bool haveGlyphs = false; Vector<CGGlyph, 512> glyphs(bufferLength); if (!shouldUseCoreText(buffer, bufferLength, fontData)) { // We pass in either 256 or 512 UTF-16 characters: 256 for U+FFFF and less, 512 (double character surrogates) // for U+10000 and above. It is indeed possible to get back 512 glyphs back from the API, so the glyph buffer // we pass in must be 512. If we get back more than 256 glyphs though we'll ignore all the ones after 256, // this should not happen as the only time we pass in 512 characters is when they are surrogates. CGFontGetGlyphsForUnichars(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength); for (unsigned i = 0; i < length; ++i) { if (!glyphs[i]) setGlyphDataForIndex(offset + i, 0, 0); else { setGlyphDataForIndex(offset + i, glyphs[i], fontData); haveGlyphs = true; } } } else if (!fontData->platformData().isCompositeFontReference() && ((fontData->platformData().widthVariant() == RegularWidth) ? CTFontGetVerticalGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength) : CTFontGetGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength))) { // When buffer consists of surrogate pairs, CTFontGetVerticalGlyphsForCharacters and CTFontGetGlyphsForCharacters // place the glyphs at indices corresponding to the first character of each pair. ASSERT(!(bufferLength % length) && (bufferLength / length == 1 || bufferLength / length == 2)); unsigned glyphStep = bufferLength / length; for (unsigned i = 0; i < length; ++i) { if (!glyphs[i * glyphStep]) setGlyphDataForIndex(offset + i, 0, 0); else { setGlyphDataForIndex(offset + i, glyphs[i * glyphStep], fontData); haveGlyphs = true; } } } else { // We ask CoreText for possible vertical variant glyphs RetainPtr<CFStringRef> string = adoptCF(CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buffer, bufferLength, kCFAllocatorNull)); RetainPtr<CFAttributedStringRef> attributedString = adoptCF(CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(0, fontData->hasVerticalGlyphs() ? Vertical : Horizontal))); RetainPtr<CTLineRef> line = adoptCF(CTLineCreateWithAttributedString(attributedString.get())); CFArrayRef runArray = CTLineGetGlyphRuns(line.get()); CFIndex runCount = CFArrayGetCount(runArray); // Initialize glyph entries for (unsigned index = 0; index < length; ++index) setGlyphDataForIndex(offset + index, 0, 0); Vector<CGGlyph, 512> glyphVector; Vector<CFIndex, 512> indexVector; bool done = false; RetainPtr<CFTypeRef> fontEqualityObject = fontData->platformData().objectForEqualityCheck(); for (CFIndex r = 0; r < runCount && !done ; ++r) { // CTLine could map characters over multiple fonts using its own font fallback list. // We need to pick runs that use the exact font we need, i.e., fontData->platformData().ctFont(). CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r)); ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID()); CFDictionaryRef attributes = CTRunGetAttributes(ctRun); CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(attributes, kCTFontAttributeName)); bool gotBaseFont = CFEqual(fontEqualityObject.get(), FontPlatformData::objectForEqualityCheck(runFont).get()); if (gotBaseFont || fontData->platformData().isCompositeFontReference()) { // This run uses the font we want. Extract glyphs. CFIndex glyphCount = CTRunGetGlyphCount(ctRun); const CGGlyph* glyphs = CTRunGetGlyphsPtr(ctRun); if (!glyphs) { glyphVector.resize(glyphCount); CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), glyphVector.data()); glyphs = glyphVector.data(); } const CFIndex* stringIndices = CTRunGetStringIndicesPtr(ctRun); if (!stringIndices) { indexVector.resize(glyphCount); CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), indexVector.data()); stringIndices = indexVector.data(); } // When buffer consists of surrogate pairs, CTRunGetStringIndicesPtr and CTRunGetStringIndices // place the glyphs at indices corresponding to the first character of each pair. ASSERT(!(bufferLength % length) && (bufferLength / length == 1 || bufferLength / length == 2)); unsigned glyphStep = bufferLength / length; if (gotBaseFont) { for (CFIndex i = 0; i < glyphCount; ++i) { if (stringIndices[i] >= static_cast<CFIndex>(bufferLength)) { done = true; break; } if (glyphs[i]) { setGlyphDataForIndex(offset + (stringIndices[i] / glyphStep), glyphs[i], fontData); haveGlyphs = true; } } #if USE(APPKIT) } else { const Font* runSimple = fontData->compositeFontReferenceFont((NSFont *)runFont); if (runSimple) { for (CFIndex i = 0; i < glyphCount; ++i) { if (stringIndices[i] >= static_cast<CFIndex>(bufferLength)) { done = true; break; } if (glyphs[i]) { setGlyphDataForIndex(offset + (stringIndices[i] / glyphStep), glyphs[i], runSimple); haveGlyphs = true; } } } #endif } } } } return haveGlyphs; }
static RetainPtr<CGImageRef> createDifferenceImage(CGImageRef baseImage, CGImageRef testImage, float& difference) { size_t width = CGImageGetWidth(baseImage); size_t height = CGImageGetHeight(baseImage); size_t rowBytes = width * 4; // Draw base image in bitmap context void* baseBuffer = calloc(height, rowBytes); RetainPtr<CGContextRef> baseContext = adoptCF(CGBitmapContextCreate(baseBuffer, width, height, 8, rowBytes, CGImageGetColorSpace(baseImage), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); CGContextDrawImage(baseContext.get(), CGRectMake(0, 0, width, height), baseImage); // Draw test image in bitmap context void* buffer = calloc(height, rowBytes); RetainPtr<CGContextRef> context = adoptCF(CGBitmapContextCreate(buffer, width, height, 8, rowBytes, CGImageGetColorSpace(testImage), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); CGContextDrawImage(context.get(), CGRectMake(0, 0, width, height), testImage); // Compare the content of the 2 bitmaps void* diffBuffer = malloc(width * height); float count = 0.0f; float sum = 0.0f; float maxDistance = 0.0f; unsigned char* basePixel = (unsigned char*)baseBuffer; unsigned char* pixel = (unsigned char*)buffer; unsigned char* diff = (unsigned char*)diffBuffer; for (size_t y = 0; y < height; ++y) { for (size_t x = 0; x < width; ++x) { float red = (pixel[0] - basePixel[0]) / max<float>(255 - basePixel[0], basePixel[0]); float green = (pixel[1] - basePixel[1]) / max<float>(255 - basePixel[1], basePixel[1]); float blue = (pixel[2] - basePixel[2]) / max<float>(255 - basePixel[2], basePixel[2]); float alpha = (pixel[3] - basePixel[3]) / max<float>(255 - basePixel[3], basePixel[3]); float distance = sqrtf(red * red + green * green + blue * blue + alpha * alpha) / 2.0f; *diff++ = (unsigned char)(distance * 255.0f); if (distance >= 1.0f / 255.0f) { count += 1.0f; sum += distance; if (distance > maxDistance) maxDistance = distance; } basePixel += 4; pixel += 4; } } // Compute the difference as a percentage combining both the number of different pixels and their difference amount i.e. the average distance over the entire image if (count > 0.0f) difference = 100.0f * sum / (height * width); else difference = 0.0f; RetainPtr<CGImageRef> diffImage; // Generate a normalized diff image if there is any difference if (difference > 0.0f) { if (maxDistance < 1.0f) { diff = (unsigned char*)diffBuffer; for(size_t p = 0; p < height * width; ++p) diff[p] = diff[p] / maxDistance; } static CGColorSpaceRef diffColorspace = CGColorSpaceCreateDeviceGray(); RetainPtr<CGDataProviderRef> provider = adoptCF(CGDataProviderCreateWithData(0, diffBuffer, width * height, releaseMallocBuffer)); diffImage = adoptCF(CGImageCreate(width, height, 8, 8, width, diffColorspace, 0, provider.get(), 0, false, kCGRenderingIntentDefault)); } else free(diffBuffer); // Destroy drawing buffers if (buffer) free(buffer); if (baseBuffer) free(baseBuffer); return diffImage; }
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp) { startAnimation(); RetainPtr<CGImageRef> image = frameAtIndex(m_currentFrame); if (!image) // If it's too early we won't have an image yet. return; if (mayFillWithSolidColor()) { fillWithSolidColor(ctxt, destRect, solidColor(), styleColorSpace, compositeOp); return; } float currHeight = CGImageGetHeight(image.get()); if (currHeight <= srcRect.y()) return; CGContextRef context = ctxt->platformContext(); ctxt->save(); bool shouldUseSubimage = false; // If the source rect is a subportion of the image, then we compute an inflated destination rect that will hold the entire image // and then set a clip to the portion that we want to display. FloatRect adjustedDestRect = destRect; FloatSize selfSize = currentFrameSize(); if (srcRect.size() != selfSize) { CGInterpolationQuality interpolationQuality = CGContextGetInterpolationQuality(context); // When the image is scaled using high-quality interpolation, we create a temporary CGImage // containing only the portion we want to display. We need to do this because high-quality // interpolation smoothes sharp edges, causing pixels from outside the source rect to bleed // into the destination rect. See <rdar://problem/6112909>. shouldUseSubimage = (interpolationQuality == kCGInterpolationHigh || interpolationQuality == kCGInterpolationDefault) && srcRect.size() != destRect.size(); float xScale = srcRect.width() / destRect.width(); float yScale = srcRect.height() / destRect.height(); if (shouldUseSubimage) { FloatRect subimageRect = srcRect; float leftPadding = srcRect.x() - floorf(srcRect.x()); float topPadding = srcRect.y() - floorf(srcRect.y()); subimageRect.move(-leftPadding, -topPadding); adjustedDestRect.move(-leftPadding / xScale, -topPadding / yScale); subimageRect.setWidth(ceilf(subimageRect.width() + leftPadding)); adjustedDestRect.setWidth(subimageRect.width() / xScale); subimageRect.setHeight(ceilf(subimageRect.height() + topPadding)); adjustedDestRect.setHeight(subimageRect.height() / yScale); image.adoptCF(CGImageCreateWithImageInRect(image.get(), subimageRect)); if (currHeight < srcRect.bottom()) { ASSERT(CGImageGetHeight(image.get()) == currHeight - CGRectIntegral(srcRect).origin.y); adjustedDestRect.setHeight(CGImageGetHeight(image.get()) / yScale); } } else { adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale)); adjustedDestRect.setSize(FloatSize(selfSize.width() / xScale, selfSize.height() / yScale)); } CGContextClipToRect(context, destRect); } // If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly. if (!shouldUseSubimage && currHeight < selfSize.height()) adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height()); ctxt->setCompositeOperation(compositeOp); // Flip the coords. CGContextScaleCTM(context, 1, -1); adjustedDestRect.setY(-adjustedDestRect.bottom()); // Adjust the color space. image = imageWithColorSpace(image.get(), styleColorSpace); // Draw the image. CGContextDrawImage(context, adjustedDestRect, image.get()); ctxt->restore(); if (imageObserver()) imageObserver()->didDraw(this); }
bool ImageSource::allowSubsamplingOfFrameAtIndex(size_t) const { RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions())); if (!properties) return false; CFDictionaryRef jfifProperties = static_cast<CFDictionaryRef>(CFDictionaryGetValue(properties.get(), kCGImagePropertyJFIFDictionary)); if (jfifProperties) { CFBooleanRef isProgCFBool = static_cast<CFBooleanRef>(CFDictionaryGetValue(jfifProperties, kCGImagePropertyJFIFIsProgressive)); if (isProgCFBool) { bool isProgressive = CFBooleanGetValue(isProgCFBool); // Workaround for <rdar://problem/5184655> - Hang rendering very large progressive JPEG. Decoding progressive // images hangs for a very long time right now. Until this is fixed, don't sub-sample progressive images. This // will cause them to fail our large image check and they won't be decoded. // FIXME: Remove once underlying issue is fixed (<rdar://problem/5191418>) return !isProgressive; } } return true; }
void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const TransformationMatrix& patternTransform, const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect) { if (!nativeImageForCurrentFrame()) return; ASSERT(patternTransform.isInvertible()); if (!patternTransform.isInvertible()) // Avoid a hang under CGContextDrawTiledImage on release builds. return; CGContextRef context = ctxt->platformContext(); ctxt->save(); CGContextClipToRect(context, destRect); ctxt->setCompositeOperation(op); CGContextTranslateCTM(context, destRect.x(), destRect.y() + destRect.height()); CGContextScaleCTM(context, 1, -1); // Compute the scaled tile size. float scaledTileHeight = tileRect.height() * narrowPrecisionToFloat(patternTransform.d()); // We have to adjust the phase to deal with the fact we're in Cartesian space now (with the bottom left corner of destRect being // the origin). float adjustedX = phase.x() - destRect.x() + tileRect.x() * narrowPrecisionToFloat(patternTransform.a()); // We translated the context so that destRect.x() is the origin, so subtract it out. float adjustedY = destRect.height() - (phase.y() - destRect.y() + tileRect.y() * narrowPrecisionToFloat(patternTransform.d()) + scaledTileHeight); CGImageRef tileImage = nativeImageForCurrentFrame(); float h = CGImageGetHeight(tileImage); RetainPtr<CGImageRef> subImage; if (tileRect.size() == size()) subImage = tileImage; else { // Copying a sub-image out of a partially-decoded image stops the decoding of the original image. It should never happen // because sub-images are only used for border-image, which only renders when the image is fully decoded. ASSERT(h == height()); subImage.adoptCF(CGImageCreateWithImageInRect(tileImage, tileRect)); } #ifndef BUILDING_ON_TIGER // Leopard has an optimized call for the tiling of image patterns, but we can only use it if the image has been decoded enough that // its buffer is the same size as the overall image. Because a partially decoded CGImageRef with a smaller width or height than the // overall image buffer needs to tile with "gaps", we can't use the optimized tiling call in that case. // FIXME: Could create WebKitSystemInterface SPI for CGCreatePatternWithImage2 and probably make Tiger tile faster as well. // FIXME: We cannot use CGContextDrawTiledImage with scaled tiles on Leopard, because it suffers from rounding errors. Snow Leopard is ok. float scaledTileWidth = tileRect.width() * narrowPrecisionToFloat(patternTransform.a()); float w = CGImageGetWidth(tileImage); #ifdef BUILDING_ON_LEOPARD if (w == size().width() && h == size().height() && scaledTileWidth == tileRect.width() && scaledTileHeight == tileRect.height()) #else if (w == size().width() && h == size().height()) #endif CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), subImage.get()); else { #endif // On Leopard, this code now only runs for partially decoded images whose buffers do not yet match the overall size of the image. // On Tiger this code runs all the time. This code is suboptimal because the pattern does not reference the image directly, and the // pattern is destroyed before exiting the function. This means any decoding the pattern does doesn't end up cached anywhere, so we // redecode every time we paint. static const CGPatternCallbacks patternCallbacks = { 0, drawPatternCallback, NULL }; CGAffineTransform matrix = CGAffineTransformMake(narrowPrecisionToCGFloat(patternTransform.a()), 0, 0, narrowPrecisionToCGFloat(patternTransform.d()), adjustedX, adjustedY); matrix = CGAffineTransformConcat(matrix, CGContextGetCTM(context)); // The top of a partially-decoded image is drawn at the bottom of the tile. Map it to the top. matrix = CGAffineTransformTranslate(matrix, 0, size().height() - h); RetainPtr<CGPatternRef> pattern(AdoptCF, CGPatternCreate(subImage.get(), CGRectMake(0, 0, tileRect.width(), tileRect.height()), matrix, tileRect.width(), tileRect.height(), kCGPatternTilingConstantSpacing, true, &patternCallbacks)); if (!pattern) { ctxt->restore(); return; } RetainPtr<CGColorSpaceRef> patternSpace(AdoptCF, CGColorSpaceCreatePattern(0)); CGFloat alpha = 1; RetainPtr<CGColorRef> color(AdoptCF, CGColorCreateWithPattern(patternSpace.get(), pattern.get(), &alpha)); CGContextSetFillColorSpace(context, patternSpace.get()); // FIXME: Really want a public API for this. It is just CGContextSetBaseCTM(context, CGAffineTransformIdentiy). wkSetPatternBaseCTM(context, CGAffineTransformIdentity); CGContextSetPatternPhase(context, CGSizeZero); CGContextSetFillColorWithColor(context, color.get()); CGContextFillRect(context, CGContextGetClipBoundingBox(context)); #ifndef BUILDING_ON_TIGER } #endif ctxt->restore(); if (imageObserver()) imageObserver()->didDraw(this); }
String contextMenuItemTagSearchWeb() { #if PLATFORM(MAC) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) RetainPtr<CFStringRef> searchProviderName = adoptCF(wkCopyDefaultSearchProviderDisplayName()); return formatLocalizedString(WEB_UI_STRING("Search with %@", "Search with search provider context menu item with provider name inserted"), searchProviderName.get()); #else return WEB_UI_STRING("Search with Google", "Search with Google context menu item"); #endif }
std::unique_ptr<NetworkStorageSession> NetworkStorageSession::createPrivateBrowsingSession(const String& identifierBase) { RetainPtr<CFStringRef> cfIdentifier = String(identifierBase + ".PrivateBrowsing").createCFString(); #if PLATFORM(COCOA) auto session = std::make_unique<NetworkStorageSession>(adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get()))); #else auto session = std::make_unique<NetworkStorageSession>(adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get(), defaultNetworkStorageSession()->platformSession()))); #endif return session; }
extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[]) { // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>. ::SetErrorMode(0); ::SetUnhandledExceptionFilter(exceptionFilter); leakChecking = false; _setmode(1, _O_BINARY); _setmode(2, _O_BINARY); initialize(); Vector<const char*> tests; for (int i = 1; i < argc; ++i) { if (!stricmp(argv[i], "--threaded")) { threaded = true; continue; } if (!stricmp(argv[i], "--dump-all-pixels")) { dumpAllPixels = true; continue; } if (!stricmp(argv[i], "--complex-text")) { forceComplexText = true; continue; } if (!stricmp(argv[i], "--print-supported-features")) { printSupportedFeatures = true; continue; } if (!stricmp(argv[i], "--pixel-tests")) { dumpPixelsForAllTests = true; continue; } tests.append(argv[i]); } policyDelegate = new PolicyDelegate(); sharedFrameLoadDelegate.adoptRef(new FrameLoadDelegate); sharedUIDelegate.adoptRef(new UIDelegate); sharedEditingDelegate.adoptRef(new EditingDelegate); sharedHistoryDelegate.adoptRef(new HistoryDelegate); // FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592> COMPtr<IWebPreferences> tmpPreferences; if (FAILED(WebKitCreateInstance(CLSID_WebPreferences, 0, IID_IWebPreferences, reinterpret_cast<void**>(&tmpPreferences)))) return -1; COMPtr<IWebPreferences> standardPreferences; if (FAILED(tmpPreferences->standardPreferences(&standardPreferences))) return -1; COMPtr<IWebPreferencesPrivate> standardPreferencesPrivate; if (FAILED(standardPreferences->QueryInterface(&standardPreferencesPrivate))) return -1; standardPreferencesPrivate->setShouldPaintNativeControls(FALSE); standardPreferences->setJavaScriptEnabled(TRUE); standardPreferences->setDefaultFontSize(16); standardPreferences->setAcceleratedCompositingEnabled(true); standardPreferences->setContinuousSpellCheckingEnabled(TRUE); if (printSupportedFeatures) { BOOL acceleratedCompositingAvailable; standardPreferences->acceleratedCompositingEnabled(&acceleratedCompositingAvailable); #if ENABLE(3D_RENDERING) // In theory, we could have a software-based 3D rendering implementation that we use when // hardware-acceleration is not available. But we don't have any such software // implementation, so 3D rendering is only available when hardware-acceleration is. BOOL threeDRenderingAvailable = acceleratedCompositingAvailable; #else BOOL threeDRenderingAvailable = FALSE; #endif printf("SupportedFeatures:%s %s\n", acceleratedCompositingAvailable ? "AcceleratedCompositing" : "", threeDRenderingAvailable ? "3DRendering" : ""); return 0; } COMPtr<IWebView> webView(AdoptCOM, createWebViewAndOffscreenWindow(&webViewWindow)); if (!webView) return -1; COMPtr<IWebIconDatabase> iconDatabase; COMPtr<IWebIconDatabase> tmpIconDatabase; if (FAILED(WebKitCreateInstance(CLSID_WebIconDatabase, 0, IID_IWebIconDatabase, (void**)&tmpIconDatabase))) return -1; if (FAILED(tmpIconDatabase->sharedIconDatabase(&iconDatabase))) return -1; if (FAILED(webView->mainFrame(&frame))) return -1; #if USE(CFNETWORK) RetainPtr<CFURLCacheRef> urlCache = sharedCFURLCache(); CFURLCacheRemoveAllCachedResponses(urlCache.get()); #endif #ifdef _DEBUG _CrtMemState entryToMainMemCheckpoint; if (leakChecking) _CrtMemCheckpoint(&entryToMainMemCheckpoint); #endif if (threaded) startJavaScriptThreads(); if (tests.size() == 1 && !strcmp(tests[0], "-")) { char filenameBuffer[2048]; printSeparators = true; while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) { char* newLineCharacter = strchr(filenameBuffer, '\n'); if (newLineCharacter) *newLineCharacter = '\0'; if (strlen(filenameBuffer) == 0) continue; runTest(filenameBuffer); } } else { printSeparators = tests.size() > 1; for (int i = 0; i < tests.size(); i++) runTest(tests[i]); } if (threaded) stopJavaScriptThreads(); delete policyDelegate; frame->Release(); #ifdef _DEBUG if (leakChecking) { // dump leaks to stderr _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); _CrtMemDumpAllObjectsSince(&entryToMainMemCheckpoint); } #endif shutDownWebKit(); return 0; }
String contextMenuItemTagLookUpInDictionary(const String& selectedString) { #if USE(CF) RetainPtr<CFStringRef> selectedCFString = truncatedStringForLookupMenuItem(selectedString).createCFString(); return formatLocalizedString(WEB_UI_STRING("Look Up '%@'", "Look Up context menu item with selected word"), selectedCFString.get()); #else return WEB_UI_STRING("Look Up '<selection>'", "Look Up context menu item with selected word").replace("<selection>", truncatedStringForLookupMenuItem(selectedString)); #endif }
static void resetDefaultsToConsistentValues(IWebPreferences* preferences) { #ifdef USE_MAC_FONTS static BSTR standardFamily = SysAllocString(TEXT("Times")); static BSTR fixedFamily = SysAllocString(TEXT("Courier")); static BSTR sansSerifFamily = SysAllocString(TEXT("Helvetica")); static BSTR cursiveFamily = SysAllocString(TEXT("Apple Chancery")); static BSTR fantasyFamily = SysAllocString(TEXT("Papyrus")); static BSTR pictographFamily = SysAllocString(TEXT("Apple Color Emoji")); #else static BSTR standardFamily = SysAllocString(TEXT("Times New Roman")); static BSTR fixedFamily = SysAllocString(TEXT("Courier New")); static BSTR sansSerifFamily = SysAllocString(TEXT("Arial")); static BSTR cursiveFamily = SysAllocString(TEXT("Comic Sans MS")); // Not actually cursive, but it's what IE and Firefox use. static BSTR fantasyFamily = SysAllocString(TEXT("Times New Roman")); static BSTR pictographFamily = SysAllocString(TEXT("Times New Roman")); #endif preferences->setStandardFontFamily(standardFamily); preferences->setFixedFontFamily(fixedFamily); preferences->setSerifFontFamily(standardFamily); preferences->setSansSerifFontFamily(sansSerifFamily); preferences->setCursiveFontFamily(cursiveFamily); preferences->setFantasyFontFamily(fantasyFamily); preferences->setPictographFontFamily(pictographFamily); preferences->setAutosaves(FALSE); preferences->setDefaultFontSize(16); preferences->setDefaultFixedFontSize(13); preferences->setMinimumFontSize(0); preferences->setJavaEnabled(FALSE); preferences->setPlugInsEnabled(TRUE); preferences->setDOMPasteAllowed(TRUE); preferences->setEditableLinkBehavior(WebKitEditableLinkOnlyLiveWithShiftKey); preferences->setFontSmoothing(FontSmoothingTypeStandard); preferences->setUsesPageCache(FALSE); preferences->setPrivateBrowsingEnabled(FALSE); preferences->setJavaScriptCanOpenWindowsAutomatically(TRUE); preferences->setJavaScriptEnabled(TRUE); preferences->setTabsToLinks(FALSE); preferences->setShouldPrintBackgrounds(TRUE); preferences->setLoadsImagesAutomatically(TRUE); if (persistentUserStyleSheetLocation) { Vector<wchar_t> urlCharacters(CFStringGetLength(persistentUserStyleSheetLocation.get())); CFStringGetCharacters(persistentUserStyleSheetLocation.get(), CFRangeMake(0, CFStringGetLength(persistentUserStyleSheetLocation.get())), (UniChar *)urlCharacters.data()); BSTR url = SysAllocStringLen(urlCharacters.data(), urlCharacters.size()); preferences->setUserStyleSheetLocation(url); SysFreeString(url); preferences->setUserStyleSheetEnabled(TRUE); } else preferences->setUserStyleSheetEnabled(FALSE); COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); if (prefsPrivate) { prefsPrivate->setAllowUniversalAccessFromFileURLs(TRUE); prefsPrivate->setAllowFileAccessFromFileURLs(TRUE); prefsPrivate->setAuthorAndUserStylesEnabled(TRUE); prefsPrivate->setDeveloperExtrasEnabled(FALSE); prefsPrivate->setExperimentalNotificationsEnabled(TRUE); prefsPrivate->setShouldPaintNativeControls(FALSE); // FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592> prefsPrivate->setJavaScriptCanAccessClipboard(TRUE); prefsPrivate->setXSSAuditorEnabled(FALSE); prefsPrivate->setFrameFlatteningEnabled(FALSE); prefsPrivate->setOfflineWebApplicationCacheEnabled(TRUE); prefsPrivate->setLoadsSiteIconsIgnoringImageLoadingPreference(FALSE); } setAlwaysAcceptCookies(false); setlocale(LC_ALL, ""); }
CFStringRef createXMLStringFromWebArchiveData(CFDataRef webArchiveData) { CFErrorRef error = 0; CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0; RetainPtr<CFMutableDictionaryRef> propertyList = adoptCF((CFMutableDictionaryRef)CFPropertyListCreateWithData(kCFAllocatorDefault, webArchiveData, kCFPropertyListMutableContainersAndLeaves, &format, &error)); if (!propertyList) { if (error) return CFErrorCopyDescription(error); return static_cast<CFStringRef>(CFRetain(CFSTR("An unknown error occurred converting data to property list."))); } RetainPtr<CFMutableArrayRef> resources = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); CFArrayAppendValue(resources.get(), propertyList.get()); while (CFArrayGetCount(resources.get())) { RetainPtr<CFMutableDictionaryRef> resourcePropertyList = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(resources.get(), 0); CFArrayRemoveValueAtIndex(resources.get(), 0); CFMutableDictionaryRef mainResource = (CFMutableDictionaryRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebMainResource")); normalizeWebResourceURL((CFMutableStringRef)CFDictionaryGetValue(mainResource, CFSTR("WebResourceURL"))); convertWebResourceDataToString(mainResource); // Add subframeArchives to list for processing CFMutableArrayRef subframeArchives = (CFMutableArrayRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebSubframeArchives")); // WebSubframeArchivesKey in WebArchive.m if (subframeArchives) CFArrayAppendArray(resources.get(), subframeArchives, CFRangeMake(0, CFArrayGetCount(subframeArchives))); CFMutableArrayRef subresources = (CFMutableArrayRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebSubresources")); // WebSubresourcesKey in WebArchive.m if (!subresources) continue; CFIndex subresourcesCount = CFArrayGetCount(subresources); for (CFIndex i = 0; i < subresourcesCount; ++i) { CFMutableDictionaryRef subresourcePropertyList = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(subresources, i); normalizeWebResourceURL((CFMutableStringRef)CFDictionaryGetValue(subresourcePropertyList, CFSTR("WebResourceURL"))); convertWebResourceResponseToDictionary(subresourcePropertyList); convertWebResourceDataToString(subresourcePropertyList); } // Sort the subresources so they're always in a predictable order for the dump CFArraySortValues(subresources, CFRangeMake(0, CFArrayGetCount(subresources)), compareResourceURLs, 0); } error = 0; RetainPtr<CFDataRef> xmlData = adoptCF(CFPropertyListCreateData(kCFAllocatorDefault, propertyList.get(), kCFPropertyListXMLFormat_v1_0, 0, &error)); if (!xmlData) { if (error) return CFErrorCopyDescription(error); return static_cast<CFStringRef>(CFRetain(CFSTR("An unknown error occurred converting property list to data."))); } RetainPtr<CFStringRef> xmlString = adoptCF(CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, xmlData.get(), kCFStringEncodingUTF8)); RetainPtr<CFMutableStringRef> string = adoptCF(CFStringCreateMutableCopy(kCFAllocatorDefault, 0, xmlString.get())); // Replace "Apple Computer" with "Apple" in the DTD declaration. CFStringFindAndReplace(string.get(), CFSTR("-//Apple Computer//"), CFSTR("-//Apple//"), CFRangeMake(0, CFStringGetLength(string.get())), 0); return string.leakRef(); }
static CFStringRef getPostScriptName(CFStringRef faceName, HDC dc) { const DWORD cMaxNameTableSize = 1024 * 1024; static HashMap<String, RetainPtr<CFStringRef> > nameMap; // Check our hash first. String faceString(faceName); RetainPtr<CFStringRef> result = nameMap.get(faceString); if (result) return result.get(); // We need to obtain the PostScript name from the name table and use it instead,. DWORD bufferSize = GetFontData(dc, 'eman', 0, NULL, 0); // "name" backwards if (bufferSize == 0 || bufferSize == GDI_ERROR || bufferSize > cMaxNameTableSize) return NULL; Vector<BYTE> bufferVector(bufferSize); BYTE* buffer = bufferVector.data(); if (GetFontData(dc, 'eman', 0, buffer, bufferSize) == GDI_ERROR) return NULL; if (bufferSize < 6) return NULL; USHORT numberOfRecords = readBigEndianWord(buffer + 2); UINT stringsOffset = readBigEndianWord(buffer + 4); if (bufferSize < stringsOffset) return NULL; BYTE* strings = buffer + stringsOffset; // Now walk each name record looking for a Mac or Windows PostScript name. UINT offset = 6; for (int i = 0; i < numberOfRecords; i++) { if (bufferSize < offset + 12) return NULL; USHORT platformID = readBigEndianWord(buffer + offset); USHORT encodingID = readBigEndianWord(buffer + offset + 2); USHORT languageID = readBigEndianWord(buffer + offset + 4); USHORT nameID = readBigEndianWord(buffer + offset + 6); USHORT length = readBigEndianWord(buffer + offset + 8); USHORT nameOffset = readBigEndianWord(buffer + offset + 10); if (platformID == 3 && encodingID == 1 && languageID == 0x409 && nameID == 6) { // This is a Windows PostScript name and is therefore UTF-16. // Pass Big Endian as the encoding. if (bufferSize < stringsOffset + nameOffset + length) return NULL; result = adoptCF(CFStringCreateWithBytes(NULL, strings + nameOffset, length, kCFStringEncodingUTF16BE, false)); break; } else if (platformID == 1 && encodingID == 0 && languageID == 0 && nameID == 6) { // This is a Mac PostScript name and is therefore ASCII. // See http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html if (bufferSize < stringsOffset + nameOffset + length) return NULL; result = adoptCF(CFStringCreateWithBytes(NULL, strings + nameOffset, length, kCFStringEncodingASCII, false)); break; } offset += 12; } if (result) nameMap.set(faceString, result); return result.get(); }
DisplaySleepDisabler::DisplaySleepDisabler(const char* reason) : m_disableDisplaySleepAssertion(0) { #if !PLATFORM(IOS) RetainPtr<CFStringRef> reasonCF = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, reason, kCFStringEncodingUTF8)); IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonCF.get(), &m_disableDisplaySleepAssertion); #else UNUSED_PARAM(reason); IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &m_disableDisplaySleepAssertion); m_systemActivityTimer.startRepeating(systemActivityInterval); #endif }
static CFDictionaryRef QTCFDictionaryCreateWithDataCallback(CFAllocatorRef allocator, const UInt8* bytes, CFIndex length) { RetainPtr<CFDataRef> data = adoptCF(CFDataCreateWithBytesNoCopy(allocator, bytes, length, kCFAllocatorNull)); if (!data) return 0; return reinterpret_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(allocator, data.get(), kCFPropertyListImmutable, 0)); }
bool GraphicsContext3D::getImageData(Image* image, unsigned int format, unsigned int type, bool premultiplyAlpha, Vector<uint8_t>& outputVector) { if (!image) return false; CGImageRef cgImage; RetainPtr<CGImageRef> decodedImage; if (image->data()) { ImageSource decoder(false); decoder.setData(image->data(), true); if (!decoder.frameCount()) return false; decodedImage = decoder.createFrameAtIndex(0); cgImage = decodedImage.get(); } else cgImage = image->nativeImageForCurrentFrame(); if (!cgImage) return false; size_t width = CGImageGetWidth(cgImage); size_t height = CGImageGetHeight(cgImage); if (!width || !height) return false; size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage); size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage); if (bitsPerComponent != 8 && bitsPerComponent != 16) return false; if (bitsPerPixel % bitsPerComponent) return false; size_t componentsPerPixel = bitsPerPixel / bitsPerComponent; SourceDataFormat srcDataFormat = kSourceFormatRGBA8; AlphaOp neededAlphaOp = kAlphaDoNothing; switch (CGImageGetAlphaInfo(cgImage)) { case kCGImageAlphaPremultipliedFirst: // This path is only accessible for MacOS earlier than 10.6.4. // This is a special case for texImage2D with HTMLCanvasElement input, // in which case image->data() should be null. ASSERT(!image->data()); if (!premultiplyAlpha) neededAlphaOp = kAlphaDoUnmultiply; switch (componentsPerPixel) { case 2: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatAR8; else srcDataFormat = kSourceFormatAR16; break; case 4: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatARGB8; else srcDataFormat = kSourceFormatARGB16; break; default: return false; } break; case kCGImageAlphaFirst: // This path is only accessible for MacOS earlier than 10.6.4. if (premultiplyAlpha) neededAlphaOp = kAlphaDoPremultiply; switch (componentsPerPixel) { case 1: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatA8; else srcDataFormat = kSourceFormatA16; break; case 2: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatAR8; else srcDataFormat = kSourceFormatAR16; break; case 4: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatARGB8; else srcDataFormat = kSourceFormatARGB16; break; default: return false; } break; case kCGImageAlphaNoneSkipFirst: // This path is only accessible for MacOS earlier than 10.6.4. switch (componentsPerPixel) { case 2: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatAR8; else srcDataFormat = kSourceFormatAR16; break; case 4: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatARGB8; else srcDataFormat = kSourceFormatARGB16; break; default: return false; } break; case kCGImageAlphaPremultipliedLast: // This is a special case for texImage2D with HTMLCanvasElement input, // in which case image->data() should be null. ASSERT(!image->data()); if (!premultiplyAlpha) neededAlphaOp = kAlphaDoUnmultiply; switch (componentsPerPixel) { case 2: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatRA8; else srcDataFormat = kSourceFormatRA16; break; case 4: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatRGBA8; else srcDataFormat = kSourceFormatRGBA16; break; default: return false; } break; case kCGImageAlphaLast: if (premultiplyAlpha) neededAlphaOp = kAlphaDoPremultiply; switch (componentsPerPixel) { case 1: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatA8; else srcDataFormat = kSourceFormatA16; break; case 2: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatRA8; else srcDataFormat = kSourceFormatRA16; break; case 4: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatRGBA8; else srcDataFormat = kSourceFormatRGBA16; break; default: return false; } break; case kCGImageAlphaNoneSkipLast: switch (componentsPerPixel) { case 2: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatRA8; else srcDataFormat = kSourceFormatRA16; break; case 4: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatRGBA8; else srcDataFormat = kSourceFormatRGBA16; break; default: return false; } break; case kCGImageAlphaNone: switch (componentsPerPixel) { case 1: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatR8; else srcDataFormat = kSourceFormatR16; break; case 3: if (bitsPerComponent == 8) srcDataFormat = kSourceFormatRGB8; else srcDataFormat = kSourceFormatRGB16; break; default: return false; } break; default: return false; } RetainPtr<CFDataRef> pixelData; pixelData.adoptCF(CGDataProviderCopyData(CGImageGetDataProvider(cgImage))); if (!pixelData) return false; const UInt8* rgba = CFDataGetBytePtr(pixelData.get()); outputVector.resize(width * height * 4); unsigned int srcUnpackAlignment = 0; size_t bytesPerRow = CGImageGetBytesPerRow(cgImage); unsigned int padding = bytesPerRow - bitsPerPixel / 8 * width; if (padding) { srcUnpackAlignment = padding + 1; while (bytesPerRow % srcUnpackAlignment) ++srcUnpackAlignment; } bool rt = packPixels(rgba, srcDataFormat, width, height, srcUnpackAlignment, format, type, neededAlphaOp, outputVector.data()); return rt; }
void MediaPlayerPrivateQuickTimeVisualContext::retrieveCurrentImage() { if (!m_visualContext) return; #if USE(ACCELERATED_COMPOSITING) if (m_qtVideoLayer) { QTPixelBuffer buffer = m_visualContext->imageForTime(0); if (!buffer.pixelBufferRef()) return; PlatformCALayer* layer = m_qtVideoLayer.get(); if (!buffer.lockBaseAddress()) { if (requiredDllsAvailable()) { if (!m_imageQueue) { m_imageQueue = adoptPtr(new WKCAImageQueue(buffer.width(), buffer.height(), 30)); m_imageQueue->setFlags(WKCAImageQueue::Fill, WKCAImageQueue::Fill); layer->setContents(m_imageQueue->get()); } // Debug QuickTime links against a non-Debug version of CoreFoundation, so the // CFDictionary attached to the CVPixelBuffer cannot be directly passed on into the // CAImageQueue without being converted to a non-Debug CFDictionary. Additionally, // old versions of QuickTime used a non-AAS CoreFoundation, so the types are not // interchangable even in the release case. RetainPtr<CFDictionaryRef> attachments = adoptCF(QTCFDictionaryCreateCopyWithDataCallback(kCFAllocatorDefault, buffer.attachments(), &QTCFDictionaryCreateWithDataCallback)); CFTimeInterval imageTime = QTMovieVisualContext::currentHostTime(); m_imageQueue->collect(); uint64_t imageId = m_imageQueue->registerPixelBuffer(buffer.baseAddress(), buffer.dataSize(), buffer.bytesPerRow(), buffer.width(), buffer.height(), buffer.pixelFormatType(), attachments.get(), 0); if (m_imageQueue->insertImage(imageTime, WKCAImageQueue::Buffer, imageId, WKCAImageQueue::Opaque | WKCAImageQueue::Flush, &QTPixelBuffer::imageQueueReleaseCallback, buffer.pixelBufferRef())) { // Retain the buffer one extra time so it doesn't dissappear before CAImageQueue decides to release it: QTPixelBuffer::retainCallback(buffer.pixelBufferRef()); } } else { CGImageRef image = CreateCGImageFromPixelBuffer(buffer); layer->setContents(image); CGImageRelease(image); } buffer.unlockBaseAddress(); layer->setNeedsCommit(); } } else #endif m_player->repaint(); m_visualContext->task(); }
String contextMenuItemTagLookUpInDictionary(const String& selectedString) { #if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 1060 UNUSED_PARAM(selectedString); return WEB_UI_STRING("Look Up in Dictionary", "Look Up in Dictionary context menu item"); #else #if USE(CF) RetainPtr<CFStringRef> selectedCFString = truncatedStringForLookupMenuItem(selectedString).createCFString(); return formatLocalizedString(WEB_UI_STRING("Look Up “%@”", "Look Up context menu item with selected word"), selectedCFString.get()); #else return WEB_UI_STRING("Look Up “<selection>”", "Look Up context menu item with selected word").replace("<selection>", truncatedStringForLookupMenuItem(selectedString)); #endif #endif }
void MediaPlayerPrivateAVFoundationCF::paint(GraphicsContext* context, const IntRect& rect) { if (context->paintingDisabled() || !imageGenerator(m_avfWrapper)) return; LOG(Media, "MediaPlayerPrivateAVFoundationCF::paint(%p)", this); setDelayCallbacks(true); RetainPtr<CGImageRef> image = m_avfWrapper->createImageForTimeInRect(currentTime(), rect); if (image) { context->save(); context->translate(rect.x(), rect.y() + rect.height()); context->scale(FloatSize(1.0f, -1.0f)); context->setImageInterpolationQuality(InterpolationLow); IntRect paintRect(IntPoint(0, 0), IntSize(rect.width(), rect.height())); CGContextDrawImage(context->platformContext(), CGRectMake(0, 0, paintRect.width(), paintRect.height()), image.get()); context->restore(); image = 0; } setDelayCallbacks(false); m_videoFrameHasDrawn = true; }
int main(int argc, const char* argv[]) { #if PLATFORM(WIN) _setmode(0, _O_BINARY); _setmode(1, _O_BINARY); #endif float tolerance = 0.0f; for (int i = 1; i < argc; ++i) { if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--tolerance")) { if (i >= argc - 1) exit(1); tolerance = strtof(argv[i + 1], 0); ++i; continue; } } char buffer[2048]; RetainPtr<CGImageRef> actualImage; RetainPtr<CGImageRef> baselineImage; while (fgets(buffer, sizeof(buffer), stdin)) { // remove the CR char* newLineCharacter = strchr(buffer, '\n'); if (newLineCharacter) *newLineCharacter = '\0'; if (!strncmp("Content-Length: ", buffer, 16)) { strtok(buffer, " "); int imageSize = strtol(strtok(0, " "), 0, 10); if (imageSize > 0 && !actualImage) actualImage = createImageFromStdin(imageSize); else if (imageSize > 0 && !baselineImage) baselineImage = createImageFromStdin(imageSize); else fputs("error, image size must be specified.\n", stderr); } if (actualImage && baselineImage) { RetainPtr<CGImageRef> diffImage; float difference = 100.0f; if ((CGImageGetWidth(actualImage.get()) == CGImageGetWidth(baselineImage.get())) && (CGImageGetHeight(actualImage.get()) == CGImageGetHeight(baselineImage.get())) && (imageHasAlpha(actualImage.get()) == imageHasAlpha(baselineImage.get()))) { diffImage = createDifferenceImage(actualImage.get(), baselineImage.get(), difference); // difference is passed by reference if (difference <= tolerance) difference = 0.0f; else { difference = roundf(difference * 100.0f) / 100.0f; difference = max(difference, 0.01f); // round to 2 decimal places } } else fputs("error, test and reference image have different properties.\n", stderr); if (difference > 0.0f) { if (diffImage) { RetainPtr<CFMutableDataRef> imageData(AdoptCF, CFDataCreateMutable(0, 0)); RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0)); CGImageDestinationAddImage(imageDest.get(), diffImage.get(), 0); CGImageDestinationFinalize(imageDest.get()); printf("Content-Length: %lu\n", CFDataGetLength(imageData.get())); fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout); } fprintf(stdout, "diff: %01.2f%% failed\n", difference); } else fprintf(stdout, "diff: %01.2f%% passed\n", difference); actualImage = 0; baselineImage = 0; } fflush(stdout); } return 0; }
void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge) { LOG(Network, "CFNet - didReceiveAuthenticationChallenge()"); ASSERT(d->m_currentWebChallenge.isNull()); // Since CFURLConnection networking relies on keeping a reference to the original CFURLAuthChallengeRef, // we make sure that is actually present ASSERT(challenge.cfURLAuthChallengeRef()); ASSERT(challenge.authenticationClient() == this); // Should be already set. #if !PLATFORM(WIN) // Proxy authentication is handled by CFNetwork internally. We can get here if the user cancels // CFNetwork authentication dialog, and we shouldn't ask the client to display another one in that case. if (challenge.protectionSpace().isProxy()) { // Cannot use receivedRequestToContinueWithoutCredential(), because current challenge is not yet set. CFURLConnectionUseCredential(d->m_connection.get(), 0, challenge.cfURLAuthChallengeRef()); return; } #endif if (!d->m_user.isNull() && !d->m_pass.isNull()) { RetainPtr<CFURLCredentialRef> credential = adoptCF(CFURLCredentialCreate(kCFAllocatorDefault, d->m_user.createCFString().get(), d->m_pass.createCFString().get(), 0, kCFURLCredentialPersistenceNone)); URL urlToStore; if (challenge.failureResponse().httpStatusCode() == 401) urlToStore = challenge.failureResponse().url(); CredentialStorage::set(core(credential.get()), challenge.protectionSpace(), urlToStore); CFURLConnectionUseCredential(d->m_connection.get(), credential.get(), challenge.cfURLAuthChallengeRef()); d->m_user = String(); d->m_pass = String(); // FIXME: Per the specification, the user shouldn't be asked for credentials if there were incorrect ones provided explicitly. return; } if (!client() || client()->shouldUseCredentialStorage(this)) { if (!d->m_initialCredential.isEmpty() || challenge.previousFailureCount()) { // The stored credential wasn't accepted, stop using it. // There is a race condition here, since a different credential might have already been stored by another ResourceHandle, // but the observable effect should be very minor, if any. CredentialStorage::remove(challenge.protectionSpace()); } if (!challenge.previousFailureCount()) { Credential credential = CredentialStorage::get(challenge.protectionSpace()); if (!credential.isEmpty() && credential != d->m_initialCredential) { ASSERT(credential.persistence() == CredentialPersistenceNone); if (challenge.failureResponse().httpStatusCode() == 401) { // Store the credential back, possibly adding it as a default for this directory. CredentialStorage::set(credential, challenge.protectionSpace(), challenge.failureResponse().url()); } RetainPtr<CFURLCredentialRef> cfCredential = adoptCF(createCF(credential)); CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); return; } } } d->m_currentWebChallenge = challenge; if (client()) client()->didReceiveAuthenticationChallenge(this, d->m_currentWebChallenge); }