NS_IMETHODIMP nsDeviceContextSpecAndroid::GetSurfaceForPrinter(gfxASurface** aSurface) { nsCAutoString tmpDir(getenv("TMPDIR")); nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(mTempFile)); NS_ENSURE_SUCCESS(rv, rv); nsCAutoString filename("tmp-printing.pdf"); mTempFile->AppendNative(filename); rv = mTempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0660); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1"); rv = stream->Init(mTempFile, -1, -1, 0); NS_ENSURE_SUCCESS(rv, rv); nsRefPtr<gfxASurface> surface; // XXX: what should we do hear for size? screen size? gfxSize surfaceSize(480, 800); surface = new gfxPDFSurface(stream, surfaceSize); NS_ABORT_IF_FALSE(surface, "valid address expected"); surface.swap(*aSurface); return NS_OK; }
GraphicsContext3DPrivate::GraphicsContext3DPrivate(GraphicsContext3D* context, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle) : m_context(context) , m_hostWindow(hostWindow) , m_surface(0) , m_platformContext(0) , m_surfaceOwner(0) , m_platformContextWatcher(0) { if (renderStyle == GraphicsContext3D::RenderToCurrentGLContext) { m_platformContext = QOpenGLContext::currentContext(); if (m_platformContext) m_surface = m_platformContext->surface(); // Watcher needed to invalidate the GL context if destroyed before this instance m_platformContextWatcher = new QtContextWatcher(m_platformContext, this); initializeOpenGLFunctions(); return; } QOpenGLContext* shareContext = 0; if (hostWindow && hostWindow->platformPageClient()) shareContext = hostWindow->platformPageClient()->openGLContextIfAvailable(); QOffscreenSurface* surface = new QOffscreenSurface; surface->create(); m_surface = surface; m_surfaceOwner = surface; m_platformContext = new QOpenGLContext(m_surfaceOwner); if (shareContext) m_platformContext->setShareContext(shareContext); if (!m_platformContext->create()) { delete m_platformContext; m_platformContext = 0; return; } makeCurrentIfNeeded(); initializeOpenGLFunctions(); #if USE(GRAPHICS_SURFACE) IntSize surfaceSize(m_context->m_currentWidth, m_context->m_currentHeight); m_surfaceFlags = GraphicsSurface::SupportsTextureTarget | GraphicsSurface::SupportsSharing; if (!surfaceSize.isEmpty()) m_graphicsSurface = GraphicsSurface::create(surfaceSize, m_surfaceFlags, m_platformContext); #endif }
NS_IMETHODIMP nsDeviceContextSpecQt::GetSurfaceForPrinter( gfxASurface** aSurface) { NS_ENSURE_ARG_POINTER(aSurface); *aSurface = nsnull; double width, height; mPrintSettings->GetEffectivePageSize(&width, &height); // If we're in landscape mode, we'll be rotating the output -- // need to swap width & height. PRInt32 orientation; mPrintSettings->GetOrientation(&orientation); if (nsIPrintSettings::kLandscapeOrientation == orientation) { double tmp = width; width = height; height = tmp; } // convert twips to points width /= TWIPS_PER_POINT_FLOAT; height /= TWIPS_PER_POINT_FLOAT; DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", mPath, width, height)); QTemporaryFile file; if(!file.open()) { return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; } file.setAutoRemove(false); nsresult rv = NS_NewNativeLocalFile( nsDependentCString(file.fileName().toAscii().constData()), PR_FALSE, getter_AddRefs(mSpoolFile)); if (NS_FAILED(rv)) { file.remove(); return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; } mSpoolName = file.fileName().toUtf8().constData(); mSpoolFile->SetPermissions(0600); nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1"); rv = stream->Init(mSpoolFile, -1, -1, 0); if (NS_FAILED(rv)) return rv; PRInt16 format; mPrintSettings->GetOutputFormat(&format); nsRefPtr<gfxASurface> surface; gfxSize surfaceSize(width, height); if (format == nsIPrintSettings::kOutputFormatNative) { if (mIsPPreview) { // There is nothing to detect on Print Preview, use PS. // TODO: implement for Qt? //format = nsIPrintSettings::kOutputFormatPS; return NS_ERROR_NOT_IMPLEMENTED; } format = nsIPrintSettings::kOutputFormatPDF; } if (format == nsIPrintSettings::kOutputFormatPDF) { surface = new gfxPDFSurface(stream, surfaceSize); } else { return NS_ERROR_NOT_IMPLEMENTED; } NS_ABORT_IF_FALSE(surface, "valid address expected"); surface.swap(*aSurface); return NS_OK; }
PrimitiveSurface * Material::getSurface( DisplayDevice * pDisplay, Image::Link pImage, int nFrame, bool bMipMap ) { // generate a unique key from the components WidgetKey nKey = pImage.key() + nFrame; if ( bMipMap ) nKey += MIPMAP_KEY; AutoLock lock( &sm_SurfaceHashLock ); SurfaceHash::Iterator it = sm_SurfaceHash.find( nKey ); if ( it.valid() ) return *it; lock.release(); // surface not found, create and cache the surface PrimitiveSurface::Ref pSurface; if ( pImage.valid() && pImage->frameCount() > 0 ) { // find a format for our surface first, findBestFormat() will always try to use the images current format // if supported by the hardware. ColorFormat::Format eFormat = findBestFormat( pDisplay, pImage, true ); if ( eFormat == ColorFormat::INVALID ) { TRACE( "ERROR: Failed to find a suitable surface format for texture!" ); return NULL; } SizeInt imageSize( pImage->size() ); SizeInt maxSize( pDisplay->textureMaxSize() ); SizeInt minSize( pDisplay->textureMinSize() ); // use the smaller max size maxSize.width = Min( sm_MaxTextureSize.width, maxSize.width ); maxSize.height = Min( sm_MaxTextureSize.height, maxSize.height ); // validate the texture dimensions SizeInt validSize( Max( Min( imageSize.width, maxSize.width ), minSize.width), Max( Min( imageSize.height, maxSize.height ), minSize.height) ); if ( pDisplay->textureP2() && !pImage->isP2() ) validSize = SizeInt( 1 << GetLastBit( validSize.width ), 1 << GetLastBit( validSize.height) ); if ( pDisplay->textureSquare() && validSize.width != validSize.height ) validSize = SizeInt( Max( validSize.width, validSize.height ), Max( validSize.width, validSize.height) ); if ( validSize != imageSize || eFormat != pImage->format() ) { // image is the wrong size or format, make a copy so we don't modify the original.. pImage = new Image( *pImage ); if ( pImage->size() != validSize ) { // image has to be resized - switch the format to an uncompressed format, DXT compression is too slow // to do on the fly.. eFormat = findBestFormat( pDisplay, pImage, false ); if ( eFormat != pImage->format() ) { TRACE( CharString().format( "Image: Reformat %s -> %s", ColorFormat::formatText( pImage->format() ), ColorFormat::formatText( eFormat ) ) ); if (! pImage->setFormat( eFormat ) ) return NULL; } TRACE( CharString().format( "Image: Resize %dx%d -> %dx%d", imageSize.width, imageSize.height, validSize.width, validSize.height ) ); pImage->resample( validSize ); if ( bMipMap && pImage->mipMap() != NULL ) pImage->createMipMaps(); } else if ( pImage->format() != eFormat ) { TRACE( CharString().format( "Image: Reformat %s -> %s", ColorFormat::formatText( pImage->format() ), ColorFormat::formatText( eFormat ) ) ); if (! pImage->setFormat( eFormat ) ) return NULL; // failed to convert to the desired format.. } } if ( bMipMap && pImage->mipMap() == NULL ) bMipMap = false; // no mipmap levels in image, disable mipmaps // create the primitives, note having neither a diffuse or alpha texture is also a valid material pDisplay->create( pSurface ); // create the surface SizeInt surfaceSize( pImage->size() ); pSurface->initialize( surfaceSize.width, surfaceSize.height, eFormat, bMipMap ); nFrame = nFrame % pImage->frameCount(); Image * pMipMap = pImage; for(int i=0;i<pSurface->levels();++i) { if (! pMipMap ) { TRACE( CharString().format("ERROR: Mipmap level %d is missing!", i ) ); break; } void * pPixels = pSurface->lock( i ); if (! pPixels ) { TRACE( "ERROR: Failed to lock surface!" ); break; } memcpy( pPixels, pMipMap->frame( nFrame ), pMipMap->frameSize( nFrame ) ); pSurface->unlock(); // next mipmap level of our image.. pMipMap = pMipMap->mipMap(); } } // cache the surface now lock.set( &sm_SurfaceHashLock ); sm_SurfaceHash[ nKey ] = pSurface; return pSurface; }
NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurface) { *aSurface = nsnull; const char *path; GetPath(&path); double width, height; mPrintSettings->GetEffectivePageSize(&width, &height); // If we're in landscape mode, we'll be rotating the output -- // need to swap width & height. PRInt32 orientation; mPrintSettings->GetOrientation(&orientation); if (nsIPrintSettings::kLandscapeOrientation == orientation) { double tmp = width; width = height; height = tmp; } // convert twips to points width /= TWIPS_PER_POINT_FLOAT; height /= TWIPS_PER_POINT_FLOAT; DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", path, width, height)); nsresult rv; // Spool file. Use Glib's temporary file function since we're // already dependent on the gtk software stack. gchar *buf; gint fd = g_file_open_tmp("XXXXXX.tmp", &buf, nsnull); if (-1 == fd) return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; close(fd); rv = NS_NewNativeLocalFile(nsDependentCString(buf), PR_FALSE, getter_AddRefs(mSpoolFile)); if (NS_FAILED(rv)) { unlink(buf); return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; } mSpoolName = buf; g_free(buf); mSpoolFile->SetPermissions(0600); nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1"); rv = stream->Init(mSpoolFile, -1, -1, 0); if (NS_FAILED(rv)) return rv; PRInt16 format; mPrintSettings->GetOutputFormat(&format); nsRefPtr<gfxASurface> surface; gfxSize surfaceSize(width, height); // Determine the real format with some GTK magic if (format == nsIPrintSettings::kOutputFormatNative) { if (mIsPPreview) { // There is nothing to detect on Print Preview, use PS. format = nsIPrintSettings::kOutputFormatPS; } else { const gchar* fmtGTK = gtk_print_settings_get(mGtkPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT); if (!fmtGTK && GTK_IS_PRINTER(mGtkPrinter)) { // Likely not print-to-file, check printer's capabilities format = (gtk_printer_accepts_ps(mGtkPrinter)) ? nsIPrintSettings::kOutputFormatPS : nsIPrintSettings::kOutputFormatPDF; } else if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) { format = nsIPrintSettings::kOutputFormatPDF; } else { format = nsIPrintSettings::kOutputFormatPS; } } } if (format == nsIPrintSettings::kOutputFormatPDF) { surface = new gfxPDFSurface(stream, surfaceSize); } else { surface = new gfxPSSurface(stream, surfaceSize); } if (!surface) return NS_ERROR_OUT_OF_MEMORY; surface.swap(*aSurface); return NS_OK; }