[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-cygwin
Subject:    QPrinter_Win.cpp
From:       simon.rutishauser () web ! de (Simon Rutishauser)
Date:       2004-12-15 20:06:24
Message-ID: 20041215200624.GA3990 () thinkpad
[Download RAW message or body]

I've implemented quite a part of qprinter_win.cpp. Drawing graphic 
primitives should work now. 

Drawing text is a quite ugly hack in qpainter_win.cpp - maybe someone 
has a better solution for this?
The problem there in short:
You have to access some private methods of QTextEngine (or was ist 
QScriptItem, don't remember) to draw the text from within qprinter_win - 
this is not possible because qprinter_win is no _friend_ of the above 
class. Bad luck.
Drawing on the printer from within qpainter_win (which is a friend of 
the needed class) doesn't work because I haven't got the deivce context 
there.
Current solution: Drawing on a QPixmap and printing just as a normal 
pixmap.

There might be lots of bugs all over. Some code has not yet been _really_ tested, rather 
just implemented (especially the brushes and raster-op part)

I attached the complete qprinter_win.cpp (lots of code by me and I don't 
think anyone has changed anything there in the meanwhile) and a file 
containing the changed QPainter::drawTextItem() function.

Somehow cvs diff (-u) does not seem to produce usable results for me. 
Bad luck.

Simon

["qpainter_drawtextitem.txt" (text/plain)]

void QPainter::drawTextItem( int x, int y, const QTextItem & ti, int textFlags )
{
    if ( testf( ExtDev ) ) {
        QPDevCmdParam param[ 2 ];
        QPoint p( x, y );
        param[ 0 ].point = &p;
        param[ 1 ].textItem = &ti;
        //bool retval = pdev->cmd( QPaintDevice::PdcDrawTextItem, this, param );

        //Create Pixmap and write there...
        QTextEngine *engine = ti.engine;
        QScriptItem *si = &engine->items[ ti.item ];

        engine->shape( ti.item );
        QFontEngine *fe = si->fontEngine;
        assert( fe != 0 );

        QPixmap pixmap = QPixmap( si->width, fe->tm.w.tmHeight );
        pixmap.fill();

        fe->draw( &QPainter( &pixmap ), si->x, si->y, engine, si, textFlags );
        pixmap.setMask( pixmap.createHeuristicMask() );

        param[ 1 ].pixmap = &pixmap;
        bool retval = pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param );

        if ( !retval || !hdc )
            return ;
    }

    QTextEngine *engine = ti.engine;
    QScriptItem *si = &engine->items[ ti.item ];

    engine->shape( ti.item );
    QFontEngine *fe = si->fontEngine;
    assert( fe != 0 );

    x += si->x;
    y += si->y;

    fe->draw( this, x, y, engine, si, textFlags );
}

["qprinter_win-20041215-2105.cpp" (text/x-c++src)]

/****************************************************************************
** $Id: qprinter_win.cpp,v 1.1.2.6.2.8 2004/09/25 11:53:39 atomice Exp $
**
** Implementation of QPrinter class for Unix
**
** Created : 20030119
**
** Copyright (C) 2003 Holger Schroeder
** Copyright (C) 2003 Richard Lärkäng
** Copyright (C) 2004 Tom and Timi Cecka
** Copyright (C) 2004 Andreas Hausladen
** Copyright (C) 2004 Ralf Habacker
** Copyright (C) 2004 Peter Kuemmel
** Copyright (C) 2004 Simon Rutishauser
**
** This file is part of the kernel module of the Qt GUI Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
**   information about Qt Commercial License Agreements.
** See http://www.trolltech.com/qpl/ for QPL licensing information.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact kde-cygwin@kde.org if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/

#include "qplatformdefs.h"

// POSIX Large File Support redefines open -> open64
static inline int qt_open( const char *pathname, int flags, mode_t mode )
{
    return ::open( pathname, flags, mode );
}
#if defined(open)
# undef open
#endif

#include "qprinter.h"
#include "qt_windows.h"

#ifndef QT_NO_PRINTER

#include "qapplication.h"
#include "qimage.h"
#include "qpaintdevicemetrics.h"
#include "qpen.h"
#include "qpixmap.h"
#include "qpointarray.h"

#include "qtextengine_p.h"
#include "qtextlayout_p.h"

#include <stdlib.h>
#include <math.h>

// NOT REVISED


class QPrinterPrivate
{
public:
    bool marginsSpecified;
    uint topMargin;
    uint leftMargin;
    uint bottomMargin;
    uint rightMargin;
};

#define D ( (QPrinterPrivate*) d )


/*****************************************************************************
  QPrinter member functions
 *****************************************************************************/

// QPrinter states

#define PST_IDLE        0
#define PST_ACTIVE      1
#define PST_ERROR       2
#define PST_ABORTED     3

// Default values for QPrinter members

struct PrinterDefaults
{
    QString printerName;
    bool outputToFile;
    QString outputFileName;
    QPrinter::Orientation orientation;
    QPrinter::PageSize pageSize;
    QPrinter::PageOrder pageOrder;
    QPrinter::ColorMode colorMode;
    int numCopies;
};

static PrinterDefaults * globalPrinterDefaults = 0;

/*!
    Constructs a printer paint device with mode \a m.

    \sa QPrinter::PrinterMode
*/

QPrinter::QPrinter( PrinterMode m )
        : QPaintDevice( QInternal::Printer | QInternal::ExternalDevice )
{
    viewOffsetDone = false;
    painter = 0;
    hdevmode = GlobalAlloc( GHND, sizeof( DEVMODE ) );
    //hdevnames = GlobalAlloc(GHND,sizeof(DEVNAMES));

    orient = Portrait;
    page_size = A4;
    page_order = FirstPageFirst;
    printer_name = QString( "" );
    color_mode = Color;
    ncopies = 1;
    from_pg = to_pg = min_pg = max_pg = 0;
    state = PST_IDLE;
    output_file = FALSE;
    to_edge = FALSE;
    paper_source = OnlyOne;
    switch ( m ) {
    case ScreenResolution:
        res = 72;
        break;
    case Compatible:
    case PrinterResolution:
        res = 72;
        break;
    case HighResolution:
        res = 600;
    }

    d = new QPrinterPrivate;
    d->marginsSpecified = false;
    //d->printerOptions = 0;
    setOptionEnabled( PrintToFile, TRUE );
    setOptionEnabled( PrintPageRange, TRUE );
    setPrintRange( AllPages );
}

/*!
    Destroys the printer paint device and cleans up.
*/

QPrinter::~QPrinter()
{
    GlobalFree( hdevmode );
    //GlobalFree(hdevnames);
    delete d;
}


/*!
    Advances to a new page on the printer. Returns TRUE if successful;
    otherwise returns FALSE.
*/

bool QPrinter::newPage()
{
    state = PST_ACTIVE;
    return EndPage( hdc ) && StartPage( hdc );
}


/*!
    Aborts the print job. Returns TRUE if successful; otherwise
    returns FALSE.

    \sa aborted()
*/

bool QPrinter::abort()
{
    bool aborted = AbortDoc( hdc );
    if ( aborted )
        state = PST_ABORTED;
    return aborted;
    //return state == PST_ABORTED;
}

/*!
    Returns TRUE is the printer job was aborted; otherwise returns
    FALSE.

    \sa abort()
*/

bool QPrinter::aborted() const
{
    return state == PST_ABORTED;
}

/*!
    Sets the printer name to \a name.

    The default printer will be used if no printer name is set.

    Under X11, the \c PRINTER environment variable defines the default
    printer.  Under any other window system, the window system defines
    the default printer.

    \sa printerName()
*/

void QPrinter::setPrinterName( const QString &name )
{
    if ( state != 0 ) {
#if defined(QT_CHECK_STATE)
        qWarning( "QPrinter::setPrinterName: Cannot do this during printing" );
#endif

        return ;
    }
    printer_name = name;
}

static void deleteGlobalPrinterDefaults()
{
    delete globalPrinterDefaults;
    globalPrinterDefaults = 0;
}

/*!
    Opens a printer setup dialog, with parent \a parent, and asks the
    user to specify which printer they wish to use and what settings
    it should have.

    Returns TRUE if the user pressed "OK" to print, or FALSE if the
    user cancelled the operation.
*/

bool QPrinter::setup( QWidget * parent )
{
    //resolution? duplex? custom paper size?

    //get default printer name in format printername
    PRINTDLG pd;
    memset ( ( void * ) & pd, 0, sizeof( PRINTDLG ) );

    pd.lStructSize = sizeof( PRINTDLG );
    pd.hwndOwner = parent->winId();
    pd.hInstance = 0;

    /*DEVNAMES* devnames = static_cast<DEVNAMES*>(hdevnames);
    devnames->wDefault = 0;
    devnames->wDeviceOffset = 0;
    devnames->wDriverOffset = 0;
    devnames->wOutputOffset = 0;*/

    DEVMODE* devmode = static_cast<DEVMODE*>( hdevmode );
    memset ( ( void * ) devmode, 0, sizeof( DEVMODE ) );

    if ( printerName().length() != 0 )
        QT_WA( wcsncpy( ( LPWSTR ) devmode->dmDeviceName, ( LPWSTR ) \
                printerName().left( 31 ).ucs2(), 32 );,
               strncpy( ( LPSTR ) devmode->dmDeviceName, ( LPSTR ) \
printerName().left( 31 ).latin1(), 32 ); )  else
            devmode->dmDeviceName[ 0 ] = '\0';

    devmode->dmSize = sizeof( DEVMODE );
    /*devmode->dmSpecVersion = 0;
    devmode->dmDriverVersion = 0;
    devmode->dmDriverExtra = 0;*/

    devmode->dmFields = DM_ORIENTATION | DM_PAPERSIZE | DM_COPIES | DM_DEFAULTSOURCE \
| DM_COLOR;  devmode->dmOrientation = orientation() == Portrait ? DMORIENT_PORTRAIT : \
DMORIENT_LANDSCAPE;

    devmode->dmPaperLength = 0;
    devmode->dmPaperWidth = 0;
    switch ( pageSize() ) {
    case Letter:
        devmode->dmPaperSize = DMPAPER_LETTER;
        break;
    case Legal:
        devmode->dmPaperSize = DMPAPER_LEGAL;
        break;
    case Executive:
        devmode->dmPaperSize = DMPAPER_EXECUTIVE;
        break;
    case A2:
        devmode->dmPaperSize = DMPAPER_A2;
        break;
    case A3:
        devmode->dmPaperSize = DMPAPER_A3;
        break;
    case A4:
        devmode->dmPaperSize = DMPAPER_A4;
        break;
    case A5:
        devmode->dmPaperSize = DMPAPER_A5;
        break;
    case B4:
        devmode->dmPaperSize = DMPAPER_B4;
        break;
    case B5:
        devmode->dmPaperSize = DMPAPER_B5;
        break;
    case C5E:
        devmode->dmPaperSize = DMPAPER_ENV_C5;
        break;
    case Comm10E:
        devmode->dmPaperSize = DMPAPER_ENV_10;
        break;
    case DLE:
        devmode->dmPaperSize = DMPAPER_ENV_DL;
        break;
    case Folio:
        devmode->dmPaperSize = DMPAPER_FOLIO;
        break;
    case Ledger:
        devmode->dmPaperSize = DMPAPER_LEDGER;
        break;
    case Tabloid:
        devmode->dmPaperSize = DMPAPER_TABLOID;
        break;
    case Custom:
        devmode->dmPaperSize = 0;
        //devmode->dmPaperLength =
        //devmode->dmPaperWidth =
        break;
    }

    /*POINTL pointl;
    pointl.x = 0;
    pointl.y = 0;
    devmode->dmPosition = pointl;*/

    devmode->dmScale = 100;
    devmode->dmCopies = numCopies();
    switch ( paperSource() ) {
    case OnlyOne:
        devmode->dmDefaultSource = DMBIN_ONLYONE;
        break;
    case Lower:
        devmode->dmDefaultSource = DMBIN_LOWER;
        break;
    case Middle:
        devmode->dmDefaultSource = DMBIN_MIDDLE;
        break;
    case Manual:
        devmode->dmDefaultSource = DMBIN_MANUAL;
        break;
    case Envelope:
        devmode->dmDefaultSource = DMBIN_ENVELOPE;
        break;
    case EnvelopeManual:
        devmode->dmDefaultSource = DMBIN_ENVMANUAL;
        break;
    case Auto:
        devmode->dmDefaultSource = DMBIN_AUTO;
        break;
    case Tractor:
        devmode->dmDefaultSource = DMBIN_TRACTOR;
        break;
    case SmallFormat:
        devmode->dmDefaultSource = DMBIN_SMALLFMT;
        break;
    case LargeFormat:
        devmode->dmDefaultSource = DMBIN_LARGEFMT;
        break;
    case LargeCapacity:
        devmode->dmDefaultSource = DMBIN_LARGECAPACITY;
        break;
    case Cassette:
        devmode->dmDefaultSource = DMBIN_CASSETTE;
        break;
    case FormSource:
        devmode->dmDefaultSource = DMBIN_FORMSOURCE;
        break;
    }

    /*
    devmode->dmPrintQuality = DMRES_MEDIUM;
    devmode->dmColor = colorMode() == Color ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME;
    devmode->dmDuplex = DMDUP_SIMPLEX;
    devmode->dmYResolution = 0;
    devmode->dmTTOption = DMTT_BITMAP;
    devmode->dmCollate = DMCOLLATE_FALSE;
    qt_strncpy(devmode->dmFormName, QString("").ucs2(), 32);
    devmode->dmLogPixels = 0;
    devmode->dmBitsPerPel = 0;
    devmode->dmPelsWidth = 0;
    devmode->dmPelsHeight = 0;
    devmode->dmDisplayFlags = 0;
    devmode->dmDisplayFrequency = 0;
    #if(WINVER >= 0x0400)
     DWORD  dmICL_MMethod = DMICL_MMETHOD_NONE;
     DWORD  dmICMIntent = DMICM_SATURATE;
     DWORD  dmMediaType = DL_MMEDIA_STANDARD;
     DWORD  dmDitherType = DMDITHER_NONE;
     DWORD  dmReserved1 = 0;
     DWORD  dmReserved2 = 0;
     #if (WINVER >= 0x0500) || (_WIN32_WINNT >= 0x0400)
      DWORD  dmPanningWidth = 0;
      WORD  dmPanningHeight = 0;
     #endif
    #endif /* WINVER >= 0x0400 */

    pd.hDevMode = hdevmode;
    //pd.hDevNames = hdevnames;
    pd.hDevNames = 0;
    pd.hDC = hdc;
    pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE; //printer driver handles \
multipage and collation

    switch ( printRange() ) {
    case AllPages:
        pd.Flags |= PD_ALLPAGES;
        break;
    case Selection:
        pd.Flags |= PD_SELECTION;
        break;
    case PageRange:
        pd.Flags |= PD_PAGENUMS;
        break;
    }

    if ( !isOptionEnabled( PrintToFile ) )
        pd.Flags |= PD_HIDEPRINTTOFILE | PD_DISABLEPRINTTOFILE; //?
    if ( !isOptionEnabled( PrintSelection ) )
        pd.Flags |= PD_NOSELECTION;
    if ( !isOptionEnabled( PrintPageRange ) )
        pd.Flags |= PD_NOPAGENUMS;
    if ( outputToFile() )
        pd.Flags |= PD_PRINTTOFILE;

    pd.nFromPage = fromPage();
    pd.nToPage = toPage();
    pd.nMinPage = minPage();
    pd.nMaxPage = maxPage();
    pd.nCopies = numCopies();

    if ( !PrintDlg( &pd ) ) {
        return false;
    }

    if ( hdevmode != 0 ) {
        setPrinterName( qt_winQString( devmode->dmDeviceName ) );
        setPrintProgram( qt_winQString( devmode->dmDeviceName ) );

        if ( devmode->dmFields & DM_ORIENTATION )
            setOrientation( devmode->dmOrientation == DMORIENT_PORTRAIT ? Portrait : \
Landscape );  if ( devmode->dmFields & DM_PAPERSIZE )
            switch ( devmode->dmPaperSize ) {
            case DMPAPER_LETTER:
                setPageSize( Letter );
                break;
            case DMPAPER_LEGAL:
                setPageSize( Legal );
                break;
            case DMPAPER_EXECUTIVE:
                setPageSize( Executive );
                break;
            case DMPAPER_A2:
                setPageSize( A2 );
                break;
            case DMPAPER_A3:
                setPageSize( A3 );
                break;
            case DMPAPER_A4:
                setPageSize( A4 );
                break;
            case DMPAPER_A5:
                setPageSize( A5 );
                break;
            case DMPAPER_B4:
                setPageSize( B4 );
                break;
            case DMPAPER_B5:
                setPageSize( B5 );
                break;
            case DMPAPER_ENV_C5:
                setPageSize( C5E );
                break;
            case DMPAPER_ENV_10:
                setPageSize( Comm10E );
                break;
            case DMPAPER_ENV_DL:
                setPageSize( DLE );
                break;
            case DMPAPER_FOLIO:
                setPageSize( Folio );
                break;
            case DMPAPER_LEDGER:
                setPageSize( Ledger );
                break;
            case DMPAPER_TABLOID:
                setPageSize( Tabloid );
                break;
            default:
                setPageSize( Custom );
                //devmode->dmPaperLength
                //devmode->dmPaperWidth
                break;
            }

        if ( devmode->dmFields & DM_COPIES )
            setNumCopies( devmode->dmCopies );
        if ( devmode->dmFields & DM_DEFAULTSOURCE )
            switch ( devmode->dmDefaultSource ) {
            case DMBIN_ONLYONE:
                setPaperSource( OnlyOne );
                break;
            case DMBIN_LOWER:
                setPaperSource( Lower );
                break;
            case DMBIN_MIDDLE:
                setPaperSource( Middle );
                break;
            case DMBIN_MANUAL:
                setPaperSource( Manual );
                break;
            case DMBIN_ENVELOPE:
                setPaperSource( Envelope );
                break;
            case DMBIN_ENVMANUAL:
                setPaperSource( EnvelopeManual );
                break;
            case DMBIN_AUTO:
                setPaperSource( Auto );
                break;
            case DMBIN_TRACTOR:
                setPaperSource( Tractor );
                break;
            case DMBIN_SMALLFMT:
                setPaperSource( SmallFormat );
                break;
            case DMBIN_LARGEFMT:
                setPaperSource( LargeFormat );
                break;
            case DMBIN_LARGECAPACITY:
                setPaperSource( LargeCapacity );
                break;
            case DMBIN_CASSETTE:
                setPaperSource( Cassette );
                break;
            case DMBIN_FORMSOURCE:
                setPaperSource( FormSource );
                break;
            }
        if ( devmode->dmFields & DM_COLOR )
            setColorMode( devmode->dmColor == DMCOLOR_COLOR ? Color : GrayScale );

        if ( devmode->dmFields & DM_YRESOLUTION )
            res = devmode->dmYResolution;
        //what about dmPrintQuality? It contains x resolution
        //am I allowed to change res here? qprinter_unix.cpp does only within \
construtor  }

    if ( pd.Flags & PD_ALLPAGES )
        setPrintRange( AllPages );
    else if ( pd.Flags & PD_SELECTION )
        setPrintRange( Selection );
    else if ( pd.Flags & PD_PAGENUMS )
        setPrintRange( PageRange );

    setOutputToFile( pd.Flags & PD_PRINTTOFILE );
    setFromTo( pd.nFromPage, pd.nToPage );
    setMinMax( pd.nMinPage, pd.nMaxPage );
    setNumCopies( pd.nCopies );

    if ( pd.hDC != 0 ) {
        hdc = pd.hDC;
        StartPage( hdc );
    }
    return true;
}


static const char * const psToStr[ QPrinter::NPageSize + 1 ] =
    { "A4", "B5", "Letter", "Legal", "Executive",
      "A0", "A1", "A2", "A3", "A5", "A6", "A7", "A8", "A9", "B0", "B1",
      "B10", "B2", "B3", "B4", "B6", "B7", "B8", "B9", "C5E", "Comm10E",
      "DLE", "Folio", "Ledger", "Tabloid", 0
    };

/*!
  \internal
  Handles painter commands to the printer.
*/

bool QPrinter::cmd( int c, QPainter *paint, QPDevCmdParam *p )
{
    static const uchar dense0_pat[] = {
                                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00  };
    static const uchar dense1_pat[] = {
                                          0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, \
0xff  };
    static const uchar dense2_pat[] = {
                                          0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, \
0xff  };
    static const uchar dense3_pat[] = {
                                          0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, \
0xee  };
    static const uchar dense4_pat[] = {
                                          0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, \
0xaa  };
    static const uchar dense5_pat[] = {
                                          0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, \
0x11  };
    static const uchar dense6_pat[] = {
                                          0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, \
0x00  };
    static const uchar dense7_pat[] = {
                                          0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, \
0x00  };

    if ( hdc == 0 )
        return false;

    if ( c == PdcBegin && state == PST_IDLE ) {
        DOCINFO di;
        di.cbSize = sizeof( DOCINFO );
        di.lpszDatatype = 0;
        di.lpszDocName = doc_name.ucs2();
        di.lpszOutput = output_filename.ucs2();
        state = PST_ACTIVE;
        if ( StartDoc( hdc, &di ) == SP_ERROR ) {
            state = PST_ERROR;
            qWarning( "Error when executing StartDoc()" );
            return false;
        }
        return true;
    }

    if ( c == PdcEnd && state == PST_ACTIVE ) {
        state = PST_IDLE;
        if ( EndDoc( hdc ) == SP_ERROR ) {
            state = PST_ERROR;
            qWarning( "Error when executing EndDoc()" );
            return false;
        }
        DeleteDC( hdc );
        return true;
    }

    if ( state == PST_ACTIVE ) {
        switch ( c ) {
        case PdcDrawPoint:
            return ( MoveToEx( hdc, p[ 0 ].point->x(), p[ 0 ].point->y(), 0 ) &&
                     LineTo( hdc, p[ 0 ].point->x(), p[ 0 ].point->y() )
                   );
        case PdcMoveTo:
            return MoveToEx( hdc, p[ 0 ].point->x(), p[ 0 ].point->y(), 0 );
        case PdcLineTo:
            return LineTo( hdc, p[ 0 ].point->x(), p[ 0 ].point->y() );
        case PdcDrawLine:
            return ( MoveToEx( hdc, p[ 0 ].point->x(), p[ 0 ].point->y(), 0 ) &&
                     LineTo( hdc, p[ 1 ].point->x(), p[ 1 ].point->y() )
                   );
        case PdcDrawRect:
            return ( Rectangle( hdc, p[ 0 ].rect->x(), p[ 0 ].rect->y(),
                                p[ 0 ].rect->x() + p[ 0 ].rect->width(),
                                p[ 0 ].rect->y() + p[ 0 ].rect->height() )
                   );
        case PdcDrawRoundRect:
            return ( RoundRect ( hdc, p[ 0 ].rect->x(), p[ 0 ].rect->y(),
                                 p[ 0 ].rect->x() + p[ 0 ].rect->width(),
                                 p[ 0 ].rect->y() + p[ 0 ].rect->height(),
                                 p[ 1 ].ival,
                                 p[ 2 ].ival )
                   );
        case PdcDrawEllipse:
            return ( Ellipse( hdc, p[ 0 ].rect->x(), p[ 0 ].rect->y(),
                              p[ 0 ].rect->x() + p[ 0 ].rect->width(),
                              p[ 0 ].rect->y() + p[ 0 ].rect->height() )
                   );
        case PdcDrawArc: {
                const int inCircle = 16 * 360;
                const double outCircle = 2 * 3.141591654;
                const double factor = outCircle / inCircle;

                const int centerx = p[ 0 ].rect->x() + p[ 0 ].rect->width() / 2;
                const int centery = p[ 0 ].rect->y() + p[ 0 ].rect->height() / 2;
                const int radius = 20000;

                return ( Arc( hdc, p[ 0 ].rect->x(), p[ 0 ].rect->y(),
                              p[ 0 ].rect->x() + p[ 0 ].rect->width(),
                              p[ 0 ].rect->y() + p[ 0 ].rect->height(),
                              centerx + radius * sin( factor * p[ 1 ].ival ),
                              centery + radius * cos( factor * p[ 1 ].ival ),
                              centerx + radius * sin( factor * p[ 2 ].ival ),
                              centery + radius * cos( factor * p[ 2 ].ival ) )
                       );
            }
        case PdcDrawPie: {
                const int inCircle = 16 * 360;
                const double outCircle = 2 * 3.141591654;
                const double factor = outCircle / inCircle;

                const int centerx = p[ 0 ].rect->x() + p[ 0 ].rect->width() / 2;
                const int centery = p[ 0 ].rect->y() + p[ 0 ].rect->height() / 2;
                const int radius = 20000;

                return ( Pie( hdc, p[ 0 ].rect->x(), p[ 0 ].rect->y(),
                              p[ 0 ].rect->x() + p[ 0 ].rect->width(),
                              p[ 0 ].rect->y() + p[ 0 ].rect->height(),
                              centerx + radius * sin( factor * p[ 1 ].ival ),
                              centery + radius * cos( factor * p[ 1 ].ival ),
                              centerx + radius * sin( factor * p[ 2 ].ival ),
                              centery + radius * cos( factor * p[ 2 ].ival ) )
                       );
            }
        case PdcDrawChord: {
                const int inCircle = 16 * 360;
                const double outCircle = 2 * 3.141591654;
                const double factor = outCircle / inCircle;

                const int centerx = p[ 0 ].rect->x() + p[ 0 ].rect->width() / 2;
                const int centery = p[ 0 ].rect->y() + p[ 0 ].rect->height() / 2;
                const int radius = 20000;

                return ( Chord( hdc, p[ 0 ].rect->x(), p[ 0 ].rect->y(),
                                p[ 0 ].rect->x() + p[ 0 ].rect->width(),
                                p[ 0 ].rect->y() + p[ 0 ].rect->height(),
                                centerx + radius * sin( factor * p[ 1 ].ival ),
                                centery + radius * cos( factor * p[ 1 ].ival ),
                                centerx + radius * sin( factor * p[ 2 ].ival ),
                                centery + radius * cos( factor * p[ 2 ].ival ) )
                       );
            }
        case PdcDrawLineSegments: {
                int count = p[ 0 ].ptarr->size();
                POINT* points = new POINT[ count ];
                DWORD* polyPoints = new DWORD[ count / 2 ];

                int i;
                for ( i = 0; i < count; i++ ) {
                    QPoint qp = p[ 0 ].ptarr->point( i );
                    points[ i ].x = qp.x();
                    points[ i ].y = qp.y();
                }
                for ( i = 0; i < count / 2; i++ ) {
                    polyPoints[ i ] = 2;
                }

                int retval = PolyPolyline( hdc, points, polyPoints, count / 2 );
                delete points;
                return retval;
            }
        case PdcDrawPolyline: {
                int count = p[ 0 ].ptarr->size();
                POINT* points = new POINT[ count ];

                for ( int i = 0; i < count; i++ ) {
                    QPoint qp = p[ 0 ].ptarr->point( i );
                    points[ i ].x = qp.x();
                    points[ i ].y = qp.y();
                }
                int retval = Polyline( hdc, points, count );
                delete points;
                return retval;
            }
        case PdcDrawPolygon: {
                int count = p[ 0 ].ptarr->size();
                POINT* points = new POINT[ count ];

                for ( int i = 0; i < count; i++ ) {
                    QPoint qp = p[ 0 ].ptarr->point( i );
                    points[ i ].x = qp.x();
                    points[ i ].y = qp.y();
                }
                int retval = Polygon( hdc, points, count );
                delete points;
                return retval;
            }
        case PdcDrawCubicBezier: {
                int count = p[ 0 ].ptarr->size();
                POINT* points = new POINT[ count ];

                for ( int i = 0; i < count; i++ ) {
                    QPoint qp = p[ 0 ].ptarr->point( i );
                    points[ i ].x = qp.x();
                    points[ i ].y = qp.y();
                }
                int retval = PolyBezier( hdc, points, count );
                delete points;
                return retval;
            }
        case PdcDrawText2:
            return true;
        case PdcDrawText2Formatted:
            return true;
        case PdcDrawTextItem:
            qWarning( "Drawing textItem is not supported." );
            return false;
        case PdcDrawPixmap:
            return BitBlt( hdc, p[ 0 ].point->x(), p[ 0 ].point->y(), p[ 1 \
].pixmap->width(), p[ 1 ].pixmap->height(),  p[ 1 ].pixmap->handle(), 0, 0, SRCCOPY \
);  case PdcDrawImage: {
                QPixmap pixmap;
                if ( !pixmap.convertFromImage( p[ 1 ].image->copy(), 0 ) )
                    return false;

                return BitBlt( hdc, p[ 0 ].point->x(), p[ 0 ].point->y(), \
pixmap.width(), pixmap.height(),  pixmap.handle(), 0, 0, SRCCOPY );
            }
        case PdcSetBkColor:
            return ( SetBkColor( hdc, p[ 0 ].color->pixel() ) != CLR_INVALID );
        case PdcSetBkMode:
            if ( p[ 0 ].ival == Qt::TransparentMode )
                return SetBkMode( hdc, TRANSPARENT );
            else //Qt::OpaqueMode
                return SetBkMode( hdc, OPAQUE );
        case PdcSetROP: {
                int dm;
                switch ( p[ 0 ].ival ) {
                case Qt::CopyROP:
                    dm = R2_COPYPEN;
                    break;
                case Qt::OrROP:
                    dm = R2_MERGEPEN;
                    break;
                case Qt::XorROP:
                    dm = R2_XORPEN;
                    break;
                    //case Qt::EraseROP:
                case Qt::NotAndROP:
                    dm = R2_MASKNOTPEN;
                    break;
                case Qt::NotCopyROP:
                    dm = R2_NOTCOPYPEN;
                    break;
                case Qt::NotOrROP:
                    dm = R2_MERGENOTPEN;
                    break;
                case Qt::NotXorROP:
                    dm = R2_NOTXORPEN;
                    break;
                    //case Qt::NotEraseROP:
                case Qt::AndROP:
                    dm = R2_MASKPEN;
                    break;
                case Qt::NotROP:
                    dm = R2_NOTCOPYPEN;
                    break;
                case Qt::ClearROP:
                    dm = R2_WHITE;
                    break;
                case Qt::SetROP:
                    dm = R2_BLACK;
                    break;
                case Qt::NopROP:
                    dm = R2_NOP;
                    break;
                case Qt::AndNotROP:
                    dm = R2_MASKPENNOT;
                    break;
                case Qt::OrNotROP:
                    dm = R2_MERGEPENNOT;
                    break;
                case Qt::NandROP:
                    dm = R2_NOTMASKPEN;
                    break;
                case Qt::NorROP:
                    dm = R2_NOTMERGEPEN;
                    break;
                }
                return SetROP2( hdc, dm );
            }
        case PdcSetBrushOrigin:
            return SetBrushOrgEx( hdc, p[ 0 ].point->x(), p[ 0 ].point->y(), 0 );
        case PdcSetFont:
            return SelectObject( hdc, p[ 0 ].font->handle() );
        case PdcSetPen: {
                int penStyle = 0;
                switch ( p[ 0 ].pen->style() ) {
                case Qt::NoPen:
                    penStyle = PS_NULL;
                    break;
                case Qt::SolidLine:
                    penStyle = PS_SOLID;
                    break;
                case Qt::DashLine:
                    penStyle = PS_DASH;
                    break;
                case Qt::DotLine:
                    penStyle = PS_DOT;
                    break;
                case Qt::DashDotLine:
                    penStyle = PS_DASHDOT;
                    break;
                case Qt::DashDotDotLine:
                    PS_DASHDOTDOT;
                    break;
                }
                HPEN pen = CreatePen( penStyle, p[ 0 ].pen->width(), p[ 0 \
].pen->color().pixel() );  DeleteObject( SelectObject( hdc, pen ) );
                return pen;
            }
        case PdcSetBrush: {
                HBRUSH brush;
                switch ( p[ 0 ].brush->style() ) {
                case Qt::NoBrush: {
                        HBITMAP hbmp = CreateBitmap( 8, 8, 1, 1, ( LPBYTE ) \
dense0_pat );  DeleteObject( SelectObject( hdc, hbmp ) );
                        brush = CreatePatternBrush( hbmp );
                    }
                case Qt::Dense1Pattern: {
                        HBITMAP hbmp = CreateBitmap( 8, 8, 1, 1, ( LPBYTE ) \
dense1_pat );  DeleteObject( SelectObject( hdc, hbmp ) );
                        brush = CreatePatternBrush( hbmp );
                    }
                case Qt::Dense2Pattern: {
                        HBITMAP hbmp = CreateBitmap( 8, 8, 1, 1, ( LPBYTE ) \
dense2_pat );  DeleteObject( SelectObject( hdc, hbmp ) );
                        brush = CreatePatternBrush( hbmp );
                    }
                case Qt::Dense3Pattern: {
                        HBITMAP hbmp = CreateBitmap( 8, 8, 1, 1, ( LPBYTE ) \
dense3_pat );  DeleteObject( SelectObject( hdc, hbmp ) );
                        brush = CreatePatternBrush( hbmp );
                    }
                case Qt::Dense4Pattern: {
                        HBITMAP hbmp = CreateBitmap( 8, 8, 1, 1, ( LPBYTE ) \
dense4_pat );  DeleteObject( SelectObject( hdc, hbmp ) );
                        brush = CreatePatternBrush( hbmp );
                    }
                case Qt::Dense5Pattern: {
                        HBITMAP hbmp = CreateBitmap( 8, 8, 1, 1, ( LPBYTE ) \
dense5_pat );  DeleteObject( SelectObject( hdc, hbmp ) );
                        brush = CreatePatternBrush( hbmp );
                    }
                case Qt::Dense6Pattern: {
                        HBITMAP hbmp = CreateBitmap( 8, 8, 1, 1, ( LPBYTE ) \
dense6_pat );  DeleteObject( SelectObject( hdc, hbmp ) );
                        brush = CreatePatternBrush( hbmp );
                    }
                case Qt::Dense7Pattern: {
                        HBITMAP hbmp = CreateBitmap( 8, 8, 1, 1, ( LPBYTE ) \
dense7_pat );  DeleteObject( SelectObject( hdc, hbmp ) );
                        brush = CreatePatternBrush( hbmp );
                    }
                case Qt::HorPattern:
                    brush = CreateHatchBrush( HS_HORIZONTAL, p[ 0 \
].brush->color().pixel() );  break;
                case Qt::VerPattern:
                    brush = CreateHatchBrush( HS_VERTICAL, p[ 0 \
].brush->color().pixel() );  break;
                case Qt::CrossPattern:
                    brush = CreateHatchBrush( HS_CROSS, p[ 0 ].brush->color().pixel() \
);  break;
                case Qt::BDiagPattern:
                    brush = CreateHatchBrush( HS_FDIAGONAL, p[ 0 \
].brush->color().pixel() );  break;
                case Qt::FDiagPattern:   //really? Fwd in Qt ?= Bwd in Windows
                    brush = CreateHatchBrush( HS_BDIAGONAL, p[ 0 \
].brush->color().pixel() );  break;
                case Qt::DiagCrossPattern:   //really? Bwd in Qt ?= Fwd in Windows
                    brush = CreateHatchBrush( HS_DIAGCROSS, p[ 0 \
].brush->color().pixel() );  break;
                case Qt::CustomPattern:
                    brush = CreatePatternBrush( p[ 0 ].brush->pixmap() ->hbm() );
                    break;
                }
                DeleteObject( SelectObject( hdc, brush ) );
                return true;
            }
        case PdcSetTabStops:
        case PdcSetTabArray:
            return true;
        case PdcSetUnit:
            return true;
        case PdcSetVXform:
        case PdcSetWindow:
        case PdcSetViewport:
        case PdcSetWXform:
        case PdcSetWMatrix:
        case PdcRestoreWMatrix:
            return true;
        case PdcSetClip:
            return true;
        case PdcSetClipRegion:
            return true;
        }
    }
    return true;
}

#define L_MM(n) int((n * 720 + 127) / 254)
#define L_IN(n) int(n * 72)

struct PaperSize
{
    int width, height;
};

static const PaperSize paperSizes[ QPrinter::NPageSize ] =
    {
        {
            L_MM( 210 ), L_MM( 297 )
        }
        ,          // A4
        { L_MM( 176 ), L_MM( 250 ) },          // B5
        { L_IN( 8.5 ), L_IN( 11 ) },           // Letter
        { L_IN( 8.5 ), L_IN( 14 ) },           // Legal
        { L_IN( 7.5 ), L_IN( 10 ) },           // Executive
        { L_MM( 841 ), L_MM( 1189 ) },         // A0
        { L_MM( 594 ), L_MM( 841 ) },          // A1
        { L_MM( 420 ), L_MM( 594 ) },          // A2
        { L_MM( 297 ), L_MM( 420 ) },          // A3
        { L_MM( 148 ), L_MM( 210 ) },          // A5
        { L_MM( 105 ), L_MM( 148 ) },          // A6
        { L_MM( 74 ), L_MM( 105 ) },            // A7
        { L_MM( 52 ), L_MM( 74 ) },            // A8
        { L_MM( 37 ), L_MM( 52 ) },            // A9
        { L_MM( 1000 ), L_MM( 1414 ) },        // B0
        { L_MM( 707 ), L_MM( 1000 ) },         // B1
        { L_MM( 31 ), L_MM( 44 ) },            // B10
        { L_MM( 500 ), L_MM( 707 ) },          // B2
        { L_MM( 353 ), L_MM( 500 ) },          // B3
        { L_MM( 250 ), L_MM( 353 ) },          // B4
        { L_MM( 125 ), L_MM( 176 ) },          // B6
        { L_MM( 88 ), L_MM( 125 ) },           // B7
        { L_MM( 62 ), L_MM( 88 ) },            // B8
        { L_MM( 44 ), L_MM( 62 ) },            // B9
        { L_MM( 162 ), L_MM( 229 ) },       // C5E
        { L_IN( 4.125 ), L_IN( 9.5 ) },       // Comm10E
        { L_MM( 110 ), L_MM( 220 ) },       // DLE
        { L_IN( 8.5 ), L_IN( 13 ) },        // Folio
        { L_IN( 17 ), L_IN( 11 ) },        // Ledger
        { L_IN( 11 ), L_IN( 17 ) }     // Tabloid
    };


/*!
  Internal implementation of the virtual QPaintDevice::metric() function.

  Use the QPaintDeviceMetrics class instead.

  \internal
  Hard coded return values for PostScript under X.
*/

int QPrinter::metric( int m ) const
{
    int val;
    PageSize s = pageSize();

    switch ( m ) {
    case QPaintDeviceMetrics::PdmWidth:
        val = ( orient == Portrait ) ? paperSizes[ s ].width : paperSizes[ s \
].height;  if ( res != 72 )
            val = ( val * res + 36 ) / 72;
        if ( !fullPage() ) {
            if ( D->marginsSpecified )
                val -= D->leftMargin + D->rightMargin;
            else
                val -= 2 * margins().width();
        }
        break;
    case QPaintDeviceMetrics::PdmHeight:
        val = orient == Portrait ? paperSizes[ s ].height : paperSizes[ s ].width;
        if ( res != 72 )
            val = ( val * res + 36 ) / 72;
        if ( !fullPage() ) {
            if ( D->marginsSpecified )
                val -= D->topMargin + D->bottomMargin;
            else
                val -= 2 * margins().height();
        }
        break;
    case QPaintDeviceMetrics::PdmDpiX:
        val = res;
        break;
    case QPaintDeviceMetrics::PdmDpiY:
        val = res;
        break;
    case QPaintDeviceMetrics::PdmPhysicalDpiX:
    case QPaintDeviceMetrics::PdmPhysicalDpiY:
        val = 72;
        break;
    case QPaintDeviceMetrics::PdmWidthMM:
        // double rounding error here.  hooray.
        val = metric( QPaintDeviceMetrics::PdmWidth );
        val = ( val * 254 + 5 * res ) / ( 10 * res );
        break;
    case QPaintDeviceMetrics::PdmHeightMM:
        val = metric( QPaintDeviceMetrics::PdmHeight );
        val = ( val * 254 + 5 * res ) / ( 10 * res );
        break;
    case QPaintDeviceMetrics::PdmNumColors:
        val = 16777216;
        break;
    case QPaintDeviceMetrics::PdmDepth:
        val = 24;
        break;
    default:
        val = 0;
    }
    return val;
}


/*!
    Returns the width of the left margin and the height of the top
    margin of the printer. On Unix, this is a best-effort guess, not
    based on perfect knowledge.

    If you have called setFullPage( TRUE ), margins().width() may be
    treated as the smallest sane left margin you can use, and
    margins().height() as the smallest sane top margin you can
    use.

    If you have called setFullPage( FALSE ) (this is the default),
    margins() is automatically subtracted from the pageSize() by
    QPrinter.

    \sa setFullPage() QPaintDeviceMetrics PageSize
*/
QSize QPrinter::margins() const
{
    if ( d )
        return QSize( d->leftMargin, d->topMargin );

    if ( orient == Portrait )
        return QSize( res / 2, res / 3 );

    return QSize( res / 3, res / 2 );
}

/*!
    \overload

    Sets \a top, \a left, \a bottom and \a right to the margins of the
    printer.  On Unix, this is a best-effort guess, not based on
    perfect knowledge.

    If you have called setFullPage( TRUE ), the four values specify
    the smallest sane margins you can use.

    If you have called setFullPage( FALSE ) (this is the default),
    the margins are automatically subtracted from the pageSize() by
    QPrinter.

    \sa setFullPage() QPaintDeviceMetrics PageSize
*/
void QPrinter::margins( uint *top, uint *left, uint *bottom, uint *right ) const
{
    if ( !d ) {
        int x = orient == Portrait ? res / 2 : res / 3;
        int y = orient == Portrait ? res / 3 : res / 2;
        *top = *bottom = y;
        *left = *right = x;
    } else {
        *top = d->topMargin;
        *left = d->leftMargin;
        *bottom = d->bottomMargin;
        *right = d->rightMargin;
    }
}

/*!
  Sets the printer margins to the sizes specified in \a top, \a left,
  \a bottom and \a right.

  This function currently only has an effect on Unix systems.

  \sa margins()
*/
void QPrinter::setMargins( uint top, uint left, uint bottom, uint right )
{
    if ( !d )
        d = new QPrinterPrivate;
    d->marginsSpecified = true;
    d->topMargin = top;
    d->leftMargin = left;
    d->bottomMargin = bottom;
    d->rightMargin = right;
}

void QPrinter::reinit( void )
{
    GlobalFree( hdevmode );
    GlobalFree( hdevnames );
    hdevmode = GlobalAlloc( GHND, sizeof( DEVMODE ) );
    hdevnames = GlobalAlloc( GHND, sizeof( DEVNAMES ) );
}

void QPrinter::setActive( void )
{
    state = PST_ACTIVE;
}

void QPrinter::setIdle( void )
{
    state = PST_IDLE;
}

/*!
  Windows only, using this function is not portable! Sets the windows page size
  value that is used by the DEVMODE struct. The winPageSize value must be one of
  the DMPAPER_ defines from wingdi.h.
*/
void QPrinter::setWinPageSize( short winPageSize )
{
    PDEVMODE dev = ( PDEVMODE ) hdevmode;
    if ( dev != 0 )
        dev->dmPaperSize = winPageSize;
}

/*!
  Returns the Windows page size value as used by the DEVMODE struct
  (Windows only). Using this function is not portable.

  Use pageSize() to get the PageSize, e.g. 'A4', 'Letter', etc.
*/
short QPrinter::winPageSize() const
{
    PDEVMODE dev = ( PDEVMODE ) hdevmode;
    if ( dev == 0 )
        return 0;
    return dev->dmPaperSize;
}


#endif



_______________________________________________
kde-cygwin mailing list
kde-cygwin@kde.org
https://mail.kde.org/mailman/listinfo/kde-cygwin


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic