OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [libgui/] [src/] [tkWinPrintText.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
 
2
#ifdef _WIN32
3
 
4
#include <windows.h>
5
 
6
#include "tkInt.h"
7
#include "tkWinInt.h"
8
#include "tkPort.h"
9
#include "tkText.h"
10
 
11
#define MAXINT 32000000
12
 
13
#define HAS_3D_BORDER   1
14
#define NEW_LAYOUT      2
15
#define TOP_LINE        4
16
#define BOTTOM_LINE     8
17
 
18
 
19
#define DINFO_OUT_OF_DATE       1
20
#define REDRAW_PENDING          2
21
#define REDRAW_BORDERS          4
22
#define REPICK_NEEDED           8
23
 
24
 
25
 
26
/*
27
 * The following structure describes one line of the display, which may
28
 * be either part or all of one line of the text.
29
 */
30
 
31
typedef struct DLine {
32
    TkTextIndex index;          /* Identifies first character in text
33
                                 * that is displayed on this line. */
34
    int count;                  /* Number of characters accounted for by this
35
                                 * display line, including a trailing space
36
                                 * or newline that isn't actually displayed. */
37
    int y;                      /* Y-position at which line is supposed to
38
                                 * be drawn (topmost pixel of rectangular
39
                                 * area occupied by line). */
40
    int oldY;                   /* Y-position at which line currently
41
                                 * appears on display.  -1 means line isn't
42
                                 * currently visible on display and must be
43
                                 * redrawn.  This is used to move lines by
44
                                 * scrolling rather than re-drawing. */
45
    int height;                 /* Height of line, in pixels. */
46
    int baseline;               /* Offset of text baseline from y, in
47
                                 * pixels. */
48
    int spaceAbove;             /* How much extra space was added to the
49
                                 * top of the line because of spacing
50
                                 * options.  This is included in height
51
                                 * and baseline. */
52
    int spaceBelow;             /* How much extra space was added to the
53
                                 * bottom of the line because of spacing
54
                                 * options.  This is included in height. */
55
    int length;                 /* Total length of line, in pixels. */
56
    TkTextDispChunk *chunkPtr;  /* Pointer to first chunk in list of all
57
                                 * of those that are displayed on this
58
                                 * line of the screen. */
59
    struct DLine *nextPtr;      /* Next in list of all display lines for
60
                                 * this window.   The list is sorted in
61
                                 * order from top to bottom.  Note:  the
62
                                 * next DLine doesn't always correspond
63
                                 * to the next line of text:  (a) can have
64
                                 * multiple DLines for one text line, and
65
                                 * (b) can have gaps where DLine's have been
66
                                 * deleted because they're out of date. */
67
    int flags;                  /* Various flag bits:  see below for values. */
68
} DLine;
69
 
70
 
71
typedef struct TextDInfo {
72
    Tcl_HashTable styleTable;   /* Hash table that maps from StyleValues
73
                                 * to TextStyles for this widget. */
74
    DLine *dLinePtr;            /* First in list of all display lines for
75
                                 * this widget, in order from top to bottom. */
76
    GC copyGC;                  /* Graphics context for copying from off-
77
                                 * screen pixmaps onto screen. */
78
    GC scrollGC;                /* Graphics context for copying from one place
79
                                 * in the window to another (scrolling):
80
                                 * differs from copyGC in that we need to get
81
                                 * GraphicsExpose events. */
82
    int x;                      /* First x-coordinate that may be used for
83
                                 * actually displaying line information.
84
                                 * Leaves space for border, etc. */
85
    int y;                      /* First y-coordinate that may be used for
86
                                 * actually displaying line information.
87
                                 * Leaves space for border, etc. */
88
    int maxX;                   /* First x-coordinate to right of available
89
                                 * space for displaying lines. */
90
    int maxY;                   /* First y-coordinate below available
91
                                 * space for displaying lines. */
92
    int topOfEof;               /* Top-most pixel (lowest y-value) that has
93
                                 * been drawn in the appropriate fashion for
94
                                 * the portion of the window after the last
95
                                 * line of the text.  This field is used to
96
                                 * figure out when to redraw part or all of
97
                                 * the eof field. */
98
 
99
    /*
100
     * Information used for scrolling:
101
     */
102
 
103
    int newCharOffset;          /* Desired x scroll position, measured as the
104
                                 * number of average-size characters off-screen
105
                                 * to the left for a line with no left
106
                                 * margin. */
107
    int curPixelOffset;         /* Actual x scroll position, measured as the
108
                                 * number of pixels off-screen to the left. */
109
    int maxLength;              /* Length in pixels of longest line that's
110
                                 * visible in window (length may exceed window
111
                                 * size).  If there's no wrapping, this will
112
                                 * be zero. */
113
    double xScrollFirst, xScrollLast;
114
                                /* Most recent values reported to horizontal
115
                                 * scrollbar;  used to eliminate unnecessary
116
                                 * reports. */
117
    double yScrollFirst, yScrollLast;
118
                                /* Most recent values reported to vertical
119
                                 * scrollbar;  used to eliminate unnecessary
120
                                 * reports. */
121
 
122
    /*
123
     * The following information is used to implement scanning:
124
     */
125
 
126
    int scanMarkChar;           /* Character that was at the left edge of
127
                                 * the window when the scan started. */
128
    int scanMarkX;              /* X-position of mouse at time scan started. */
129
    int scanTotalScroll;        /* Total scrolling (in screen lines) that has
130
                                 * occurred since scanMarkY was set. */
131
    int scanMarkY;              /* Y-position of mouse at time scan started. */
132
 
133
    /*
134
     * Miscellaneous information:
135
     */
136
 
137
    int dLinesInvalidated;      /* This value is set to 1 whenever something
138
                                 * happens that invalidates information in
139
                                 * DLine structures;  if a redisplay
140
                                 * is in progress, it will see this and
141
                                 * abort the redisplay.  This is needed
142
                                 * because, for example, an embedded window
143
                                 * could change its size when it is first
144
                                 * displayed, invalidating the DLine that
145
                                 * is currently being displayed.  If redisplay
146
                                 * continues, it will use freed memory and
147
                                 * could dump core. */
148
    int flags;                  /* Various flag values:  see below for
149
                                 * definitions. */
150
} TextDInfo;
151
 
152
/*
153
 * The following structure describes how to display a range of characters.
154
 * The information is generated by scanning all of the tags associated
155
 * with the characters and combining that with default information for
156
 * the overall widget.  These structures form the hash keys for
157
 * dInfoPtr->styleTable.
158
 */
159
 
160
typedef struct StyleValues {
161
    Tk_3DBorder border;         /* Used for drawing background under text.
162
                                 * NULL means use widget background. */
163
    int borderWidth;            /* Width of 3-D border for background. */
164
    int relief;                 /* 3-D relief for background. */
165
    Pixmap bgStipple;           /* Stipple bitmap for background.  None
166
                                 * means draw solid. */
167
    XColor *fgColor;            /* Foreground color for text. */
168
    Tk_Font tkfont;             /* Font for displaying text. */
169
    Pixmap fgStipple;           /* Stipple bitmap for text and other
170
                                 * foreground stuff.   None means draw
171
                                 * solid.*/
172
    int justify;                /* Justification style for text. */
173
    int lMargin1;               /* Left margin, in pixels, for first display
174
                                 * line of each text line. */
175
    int lMargin2;               /* Left margin, in pixels, for second and
176
                                 * later display lines of each text line. */
177
    int offset;                 /* Offset in pixels of baseline, relative to
178
                                 * baseline of line. */
179
    int overstrike;             /* Non-zero means draw overstrike through
180
                                 * text. */
181
    int rMargin;                /* Right margin, in pixels. */
182
    int spacing1;               /* Spacing above first dline in text line. */
183
    int spacing2;               /* Spacing between lines of dline. */
184
    int spacing3;               /* Spacing below last dline in text line. */
185
    TkTextTabArray *tabArrayPtr;/* Locations and types of tab stops (may
186
                                 * be NULL). */
187
    int underline;              /* Non-zero means draw underline underneath
188
                                 * text. */
189
    Tk_Uid wrapMode;            /* How to handle wrap-around for this tag.
190
                                 * One of tkTextCharUid, tkTextNoneUid,
191
                                 * or tkTextWordUid. */
192
} StyleValues;
193
 
194
/*
195
 * The following structure extends the StyleValues structure above with
196
 * graphics contexts used to actually draw the characters.  The entries
197
 * in dInfoPtr->styleTable point to structures of this type.
198
 */
199
 
200
typedef struct TextStyle {
201
    int refCount;               /* Number of times this structure is
202
                                 * referenced in Chunks. */
203
    GC bgGC;                    /* Graphics context for background.  None
204
                                 * means use widget background. */
205
    GC fgGC;                    /* Graphics context for foreground. */
206
    StyleValues *sValuePtr;     /* Raw information from which GCs were
207
                                 * derived. */
208
    Tcl_HashEntry *hPtr;        /* Pointer to entry in styleTable.  Used
209
                                 * to delete entry. */
210
} TextStyle;
211
 
212
 
213
 
214
 
215
void DisplayDLineToDrawable(TkText *textPtr, DLine *dlPtr, DLine *prevPtr, TkWinDrawable *drawable);
216
 
217
/*
218
 *--------------------------------------------------------------
219
 *
220
 * PrintTextCmd --
221
 *      When invoked with the correct args this will bring up a
222
 *      standard Windows print dialog box and then print the
223
 *      contence of the text wiget.
224
 *
225
 * Results:
226
 *      Standard Tcl result.
227
 *
228
 *--------------------------------------------------------------
229
 */
230
 
231
static int
232
PrintTextCmd(clientData, interp, argc, argv)
233
     ClientData clientData;
234
     Tcl_Interp *interp;
235
     int argc;
236
     char **argv;
237
{
238
    PRINTDLG pd;
239
    Tcl_CmdInfo textCmd;
240
    TkText *textPtr;
241
    TextDInfo *dInfoPtr;
242
    DLine *dlPtr;
243
    TkWinDrawable *PrinterDrawable;
244
    Tk_Window tkwin;
245
    Tk_Item *itemPtr;
246
    int maxHeight;
247
    DLine *prevPtr;
248
    Pixmap pixmap;
249
    int bottomY = 0;             /* Initialization needed only to stop
250
                                 * compiler warnings. */
251
    DOCINFO *lpdi = malloc(sizeof(DOCINFO));
252
    TkTextIndex first, last;
253
    int numLines;
254
    HDC hDCpixmap;
255
    TkWinDCState pixmapState;
256
    DEVMODE dm;
257
    float Ptr_pixX,Ptr_pixY,Ptr_mmX,Ptr_mmY;
258
    float canv_pixX,canv_pixY,canv_mmX,canv_mmY;
259
    int page_Y_size,tiles_high,tile_y;
260
    int screenX1, screenX2, screenY1, screenY2, width, height;
261
 
262
    int saved_x;
263
    int saved_y;
264
    int saved_w;
265
    int saved_h;
266
    int saved_maxX;
267
    int saved_maxY;
268
    int saved_eof;
269
 
270
 
271
    if (argc < 2) {
272
        Tcl_AppendResult(interp, "wrong # args: should be \"",
273
                         argv[0], " text \"",
274
                         (char *) NULL);
275
        return TCL_ERROR;
276
    }
277
 
278
    /*
279
     * The second arg is the canvas widget.
280
     */
281
    if (!Tcl_GetCommandInfo(interp, argv[1], &textCmd)) {
282
        Tcl_AppendResult(interp, "couldn't get text information for \"",
283
                         argv[1], "\"", (char *) NULL);
284
        return TCL_ERROR;
285
    }
286
 
287
    memset(&dm,0,sizeof(DEVMODE));
288
    dm.dmSize = sizeof(DEVMODE);
289
    dm.dmScale = 500;
290
 
291
    memset(lpdi,0,sizeof(DOCINFO));
292
    lpdi->cbSize=sizeof(DOCINFO);
293
    lpdi->lpszDocName=malloc(255);
294
    sprintf((char*)lpdi->lpszDocName,"SN - Printing\0");
295
    lpdi->lpszOutput=NULL;
296
 
297
    textPtr = (TkText *)(textCmd.clientData);
298
 
299
    tkwin = textPtr->tkwin;
300
    dInfoPtr = textPtr->dInfoPtr;
301
    dlPtr=dInfoPtr->dLinePtr;
302
    memset(&pd,0,sizeof( PRINTDLG ));
303
    pd.lStructSize  = sizeof( PRINTDLG );
304
    pd.hwndOwner    = NULL;
305
    pd.hDevMode     = NULL;
306
    pd.hDevNames    = NULL;
307
    pd.Flags        = PD_RETURNDC|PD_NOSELECTION;
308
 
309
    /*
310
     * Get printer details.
311
     */
312
    if (!PrintDlg(&pd)) {
313
        goto done;
314
    }
315
 
316
    PrinterDrawable = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable));
317
    PrinterDrawable->type = TWD_WINDC;
318
    PrinterDrawable->winDC.hdc = pd.hDC;
319
 
320
    Ptr_pixX=(float)GetDeviceCaps(PrinterDrawable->winDC.hdc,HORZRES);
321
    Ptr_pixY=(float)GetDeviceCaps(PrinterDrawable->winDC.hdc,VERTRES);
322
    Ptr_mmX=(float)GetDeviceCaps(PrinterDrawable->winDC.hdc,HORZSIZE);
323
    Ptr_mmY=(float)GetDeviceCaps(PrinterDrawable->winDC.hdc,VERTSIZE);
324
 
325
    screenX1=0; screenY1=0;
326
    screenX2=dInfoPtr->maxX; screenY2=dInfoPtr->maxY;
327
    pixmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
328
            (screenX2 + 30),
329
            (screenY2 + 30),
330
            Tk_Depth(tkwin));
331
    width = screenX2 - screenX1;
332
    height = screenY2 - screenY1;
333
 
334
    hDCpixmap = TkWinGetDrawableDC(Tk_Display(tkwin), pixmap, &pixmapState);
335
    canv_pixX=(float)GetDeviceCaps(hDCpixmap,HORZRES);
336
    canv_pixY=(float)GetDeviceCaps(hDCpixmap,VERTRES);
337
    canv_mmX=(float)GetDeviceCaps(hDCpixmap,HORZSIZE);
338
    canv_mmY=(float)GetDeviceCaps(hDCpixmap,VERTSIZE);
339
 
340
    /*
341
     * Save text widget data.
342
     */
343
    dInfoPtr = textPtr->dInfoPtr;
344
    saved_x = dInfoPtr->x;
345
    saved_y = dInfoPtr->y;
346
    saved_w = Tk_Width(textPtr->tkwin);
347
    saved_h = Tk_Height(textPtr->tkwin);
348
    saved_maxX = dInfoPtr->maxX;
349
    saved_maxY = dInfoPtr->maxY;
350
    saved_eof = dInfoPtr->topOfEof;
351
    dInfoPtr->maxX = MAXINT;
352
    Tk_Width(textPtr->tkwin) = MAXINT;
353
 
354
    dInfoPtr->maxY  = MAXINT;
355
    Tk_Height(textPtr->tkwin) = MAXINT;
356
 
357
    /* Make the text widget big enough for all the
358
    text to be seen. */
359
 
360
    numLines = TkBTreeNumLines(textPtr->tree);
361
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
362
    TkTextMakeByteIndex(textPtr->tree, 0, 0, &first);
363
    TkTextMakeByteIndex(textPtr->tree, numLines, 100, &last);
364
#else
365
    TkTextMakeIndex(textPtr->tree, 0, 0, &first);
366
    TkTextMakeIndex(textPtr->tree, numLines, 100, &last);
367
#endif
368
    TkTextChanged(textPtr, &first, &last);
369
 
370
    /*
371
     * Set the display info flag to out-of-date.
372
     */
373
 
374
    textPtr->dInfoPtr->flags|=DINFO_OUT_OF_DATE;
375
 
376
    /*
377
     *TkTextXviewCmd will call  UpdateDisplayInfo.
378
     */
379
 
380
    TkTextXviewCmd(textPtr, interp, 2, NULL);
381
    dInfoPtr = textPtr->dInfoPtr;
382
 
383
    SetMapMode(PrinterDrawable->winDC.hdc,MM_ISOTROPIC);
384
    SetWindowExtEx(PrinterDrawable->winDC.hdc,(int)((float)canv_pixX),(int)((float)canv_pixY),NULL);
385
    SetViewportExtEx(PrinterDrawable->winDC.hdc,(int)((float)Ptr_pixX),
386
                            (int)((float)Ptr_pixY),
387
                            NULL);
388
 
389
    /*
390
     * Get max Y for text widget.
391
     */
392
    maxHeight = -1;
393
    for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL;
394
            dlPtr = dlPtr->nextPtr) {
395
        maxHeight = dlPtr->y + dlPtr->height;
396
    }
397
 
398
    /*
399
     * Calculate the number of tiles high.
400
     */
401
    page_Y_size = GetDeviceCaps(hDCpixmap,LOGPIXELSY)*(Ptr_mmY/22);
402
 
403
    tiles_high = ( maxHeight / page_Y_size ); /* start at page zero */
404
 
405
    StartDoc(pd.hDC,lpdi);
406
    for (tile_y = 0; tile_y <= tiles_high;tile_y++) {
407
        SetViewportOrgEx(pd.hDC,0,-(tile_y*Ptr_pixY),NULL);
408
 
409
        StartPage(pd.hDC);
410
 
411
        if (maxHeight > 0) {
412
            for (prevPtr = NULL, dlPtr = textPtr->dInfoPtr->dLinePtr;
413
                        (dlPtr != NULL) && (dlPtr->y < dInfoPtr->maxY);
414
                        prevPtr = dlPtr, dlPtr = dlPtr->nextPtr) {
415
                DisplayDLineToDrawable(textPtr, dlPtr, prevPtr, PrinterDrawable);
416
 
417
            }
418
        }
419
 
420
 
421
        EndPage(pd.hDC);
422
    }
423
    EndDoc(pd.hDC);
424
 
425
    /*
426
     * Restore text widget data.
427
     */
428
 
429
    dInfoPtr->x = saved_x;
430
    dInfoPtr->y = saved_y;
431
    Tk_Width(textPtr->tkwin) = saved_w;
432
    Tk_Height(textPtr->tkwin) = saved_h;
433
    dInfoPtr->maxY = saved_maxY;
434
    dInfoPtr->maxX = saved_maxX;
435
    dInfoPtr->topOfEof = saved_eof;
436
    /*
437
     * Pitch the info again.
438
     */
439
    TkTextChanged(textPtr, &first, &last);
440
 
441
    /*
442
     * Display info not valid anymore.
443
     */
444
 
445
    textPtr->dInfoPtr->flags|=DINFO_OUT_OF_DATE;
446
 
447
done:
448
    return TCL_OK;
449
 error:
450
    return TCL_ERROR;
451
}
452
 
453
 
454
 
455
static void
456
ide_delete_print_text_command(ClientData clientData)
457
{
458
  /* destructor code here.*/
459
}
460
 
461
int
462
ide_create_print_text_command (Tcl_Interp *interp)
463
{
464
 
465
    if (Tcl_CreateCommand(interp, "ide_print_text",
466
        PrintTextCmd,
467
                          NULL, NULL) == NULL)
468
        return TCL_ERROR;
469
 
470
    return TCL_OK;
471
}
472
 
473
/*
474
 *----------------------------------------------------------------------
475
 *
476
 * DisplayDLineToDrawable --
477
 *
478
 *      This procedure is invoked to draw a single line to a HDC
479
 *
480
 *----------------------------------------------------------------------
481
 */
482
 
483
static void
484
DisplayDLineToDrawable(textPtr, dlPtr, prevPtr, drawable)
485
    TkText *textPtr;            /* Text widget in which to draw line. */
486
    register DLine *dlPtr;      /* Information about line to draw. */
487
    DLine *prevPtr;             /* Line just before one to draw, or NULL
488
                                 * if dlPtr is the top line. */
489
    TkWinDrawable *drawable;    /* drawable to use for displaying.
490
                                 * Caller must make sure it's large enough
491
                                 * to hold line. */
492
{
493
    register TkTextDispChunk *chunkPtr;
494
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
495
    Display *display;
496
    int height, x;
497
 
498
    /*
499
     * First, clear the area of the line to the background color for the
500
     * text widget.
501
     */
502
 
503
    display = Tk_Display(textPtr->tkwin);
504
 
505
    for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
506
            chunkPtr = chunkPtr->nextPtr) {
507
        if (chunkPtr->displayProc == TkTextInsertDisplayProc) {
508
            /*
509
             * Already displayed the insertion cursor above.  Don't
510
             * do it again here.
511
             */
512
 
513
            continue;
514
        } else {
515
            x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curPixelOffset;
516
            if ((x + chunkPtr->width <= 0) || (x >= dInfoPtr->maxX)) {
517
                (*chunkPtr->displayProc)(chunkPtr, -chunkPtr->width,
518
                    dlPtr->y,
519
                    dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
520
                    dlPtr->baseline - dlPtr->spaceAbove, display, (unsigned long)drawable,
521
                    dlPtr->y + dlPtr->spaceAbove);
522
            } else {
523
                (*chunkPtr->displayProc)(chunkPtr, x, dlPtr->y,
524
                    dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
525
                    dlPtr->baseline - dlPtr->spaceAbove, display, (unsigned long)drawable,
526
                    dlPtr->y + dlPtr->spaceAbove);
527
            }
528
        }
529
    }
530
 
531
}
532
 
533
#endif /* _WIN */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.