|
|
1.1 root 1: #ifdef sun
2: /*
3: * The Sun X drivers are a product of Sun Microsystems, Inc. and are provided
4: * for unrestricted use provided that this legend is included on all tape
5: * media and as a part of the software program in whole or part. Users
6: * may copy or modify these drivers without charge, but are not authorized
7: * to license or distribute them to anyone else except as part of a product or
8: * program developed by the user.
9: *
10: * THE SUN X DRIVERS ARE PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND
11: * INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A
12: * PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE
13: * PRACTICE.
14: *
15: * The Sun X Drivers are provided with no support and without any obligation
16: * on the part of Sun Microsystems, Inc. to assist in their use, correction,
17: * modification or enhancement.
18: *
19: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THE SUN X
21: * DRIVERS OR ANY PART THEREOF.
22: *
23: * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24: * or profits or other special, indirect and consequential damages, even if
25: * Sun has been advised of the possibility of such damages.
26: *
27: * Sun Microsystems, Inc.
28: * 2550 Garcia Avenue
29: * Mountain View, California 94043
30: */
31:
32: #ifndef lint
33: static char sccsid[] = "@(#)text.c 2.1 86/01/28 Copyright 1986 Sun Micro";
34: #endif
35:
36: /*-
37: * Copyright (c) 1986 by Sun Microsystems, Inc.
38: */
39:
40: /*
41: * ToDo:
42: * Color
43: */
44:
45: #include "Xsun.h"
46: #ifndef stdin
47: #include <stdio.h>
48: #endif
49: #include <pixrect/memreg.h>
50: #include <pixrect/cg2reg.h>
51:
52: /* I've put in some rather ugly hacks, in the name of performance. The
53: global variables private_* are really extra parameters to the batchrop
54: routines. I did this, rather than adding parameters, because I wanted to
55: do the least violence to the "official" specs of batchrop -- this way X
56: will vaguely work on displays that don't use one of the tuned batchrops.
57: JAG */
58:
59: int private_fgcolor, private_bgcolor, private_czmask;
60:
61: extern struct pixrect *PixRect;
62:
63: PrintText(string, strlen, font, fore, back, charpad, spacepad, dstx, dsty,
64: clips, clipcount, func, zmask)
65: register unsigned char *string;
66: FONT *font;
67: int strlen, fore, back, charpad, spacepad, dstx, dsty;
68: CLIP *clips;
69: int clipcount, zmask;
70: int func;
71: {
72: extern CURSOR *CurrentCursor;
73: extern CursorDisplayed;
74: int cleft, ctop, cwidth, cheight;
75: int op;
76: extern char FBMap[];
77: #define CHUNK 400
78: unsigned char *limit = string + (strlen < CHUNK ? strlen : CHUNK);
79: register w = 0;
80: static struct pr_prpos bat[CHUNK];
81: int bsize = 0;
82: int lheight;
83: int sbot, sright;
84:
85: private_czmask = zmask;
86: private_fgcolor = fore;
87: private_bgcolor = back;
88: if (fore & 1)
89: func += 0x20;
90: if (back & 1)
91: func += 0x10;
92: func = FBMap[func];
93: #ifdef notdef
94: op = SUN_FROM_X_OP(func) /* | PIX_COLOR(fore) */ ;
95: #else
96: op = SUN_FROM_X_OP(func) | PIX_COLOR(fore);
97: #endif
98: {
99: register struct pixfont *pf = (struct pixfont *) font->data;
100: register struct pr_prpos *p = bat;
101: lheight = pf->pf_defaultsize.y;
102: if (charpad == 0 && spacepad == 0)
103: while (string < limit) {
104: register struct pixchar *pc = &(pf->pf_char[*string++]);
105: if (pc == 0 || pc->pc_pr == NULL)
106: continue;
107: p->pr = pc->pc_pr;
108: p->pos.x = pc->pc_adv.x;
109: w += p->pos.x;
110: p++;
111: bsize++;
112: }
113: else {
114: struct pixchar *space = &pf->pf_char[font->space];
115: while (string < limit) {
116: register struct pixchar *pc = &(pf->pf_char[*string++]);
117: if (pc == 0 || pc->pc_pr == NULL)
118: continue;
119: p->pr = pc->pc_pr;
120: p->pos.x = pc->pc_adv.x + charpad;
121: if (pc == space)
122: p->pos.x += spacepad;
123: w += p->pos.x;
124: p++;
125: bsize++;
126: }
127: }
128: }
129: sbot = dsty + lheight;
130: sright = dstx + w;
131: if (CursorDisplayed) {
132: extern DEVICE *CurrentDevice;
133: register vsCursor *ms = CurrentDevice->mouse;
134: register CURSOR *cs = CurrentCursor;
135: if (ms->y < sbot && ms->x < sright
136: && ms->y + cs->height > dsty
137: && ms->x + cs->width > dstx)
138: DisplayCursor(NULL);
139: }
140: do {
141: GetNextClip(clips, cleft, ctop, cwidth, cheight);
142: if (dsty >= ctop && sbot <= ctop + cheight
143: && dstx >= cleft && sright <= cleft + cwidth)
144: pr_batchrop(PixRect, dstx - bat[0].pos.x, dsty,
145: op | PIX_DONTCLIP, bat, bsize);
146: else {
147: struct pixrect *region;
148: if (dsty > ctop + cheight)
149: continue;
150: if (dsty + lheight <= ctop)
151: continue;
152: region = pr_region(PixRect, cleft, ctop, cwidth, cheight);
153: pr_batchrop(region, dstx - cleft - bat[0].pos.x,
154: dsty - ctop,
155: op, bat, bsize);
156: pr_destroy(region);
157: }
158: } while (--clipcount > 0);
159: if (!CursorDisplayed)
160: DisplayCursor(CurrentCursor);
161: }
162:
163: PrintTextMask(string, strlen, font, srcpix, charpad, spacepad, dstx, dsty,
164: clips, clipcount, func, zmask)
165: unsigned char *string;
166: FONT *font;
167: int strlen, srcpix, charpad, spacepad, dstx, dsty;
168: CLIP *clips;
169: int clipcount, zmask;
170: register int func;
171: {
172: extern CURSOR *CurrentCursor;
173: extern CursorDisplayed;
174: int cleft, ctop, cwidth, cheight;
175: int op;
176: extern char SSMap[];
177: #define CHUNK 400
178: unsigned char *limit = string + (strlen < CHUNK ? strlen : CHUNK);
179: register w = 0;
180: static struct pr_prpos bat[CHUNK];
181: int bsize = 0;
182: int lheight;
183: int sbot, sright;
184:
185:
186: SetZmask(PixRect, &zmask);
187: private_bgcolor = -1;
188: private_fgcolor = srcpix;
189: if (PixRect->pr_depth == 1) {
190: if ((srcpix & 1) == 0)
191: func += 0x10;
192: op = SUN_FROM_X_OP(SSMap[func]) & PIX_SRC | PIX_NOT(PIX_SRC) & PIX_DST;
193: }
194: else
195: op = SUN_FROM_X_OP(func);
196: if (PixRect->pr_depth > 1)
197: op |= PIX_COLOR(srcpix);
198: {
199: register struct pixfont *pf = (struct pixfont *) font->data;
200: register struct pr_prpos *p = bat;
201: lheight = pf->pf_defaultsize.y;
202: if (charpad == 0 && spacepad == 0)
203: while (string < limit) {
204: register struct pixchar *pc = &(pf->pf_char[*string++]);
205: if (pc == 0)
206: continue;
207: p->pr = pc->pc_pr;
208: p->pos.x = pc->pc_adv.x;
209: w += p->pos.x;
210: p++;
211: bsize++;
212: }
213: else {
214: struct pixchar *space = &pf->pf_char[font->space];
215: while (string < limit) {
216: register struct pixchar *pc = &(pf->pf_char[*string++]);
217: if (pc == 0)
218: continue;
219: p->pr = pc->pc_pr;
220: p->pos.x = pc->pc_adv.x + charpad;
221: if (pc == space)
222: p->pos.x += spacepad;
223: w += p->pos.x;
224: p++;
225: bsize++;
226: }
227: }
228: }
229: sbot = dsty + lheight;
230: sright = dstx + w;
231: if (CursorDisplayed) {
232: extern DEVICE *CurrentDevice;
233: register vsCursor *ms = CurrentDevice->mouse;
234: register CURSOR *cs = CurrentCursor;
235: if (ms->y < sbot && ms->x < sright
236: && ms->y + cs->height > dsty
237: && ms->x + cs->width > dstx)
238: DisplayCursor(NULL);
239: }
240: do {
241: GetNextClip(clips, cleft, ctop, cwidth, cheight);
242: if (dsty >= ctop && sbot <= ctop + cheight
243: && dstx >= cleft && sright <= cleft + cwidth)
244: pr_batchrop(PixRect, dstx - bat[0].pos.x, dsty,
245: op | PIX_DONTCLIP, bat, bsize);
246: else {
247: struct pixrect *region;
248: if (dsty > ctop + cheight)
249: continue;
250: if (dsty + lheight <= ctop)
251: continue;
252: region = pr_region(PixRect, cleft, ctop, cwidth, cheight);
253: pr_batchrop(region, dstx - cleft - bat[0].pos.x,
254: dsty - ctop,
255: op, bat, bsize);
256: pr_destroy(region);
257: }
258: } while (--clipcount > 0);
259: if (!CursorDisplayed)
260: DisplayCursor(CurrentCursor);
261: {
262: static allmask = -1;
263: SetZmask(PixRect, &allmask);
264: }
265: }
266:
267:
268: /*
269: * Copyright (c) 1983 by Sun Microsystems, Inc.
270: */
271:
272: /*
273: * Memory batchrop
274: */
275:
276:
277: extern char pr_reversedst[];
278: extern struct pixrectops mem_ops;
279:
280:
281:
282: #define MEMBATCH(IfClip, IfMask, op, IfReverse) \
283: for (; --count >= 0; src++) { \
284: dst.pos.x += src->pos.x; \
285: dp = dp0 + (((dskew = xoff0 + dst.pos.x) >> 3) & ~1); \
286: dskew &= 0xF; \
287: spr = src->pr; \
288: sizex = spr->pr_size.x; \
289: sizey = spr->pr_size.y; \
290: sprd = mpr_d(spr); \
291: if (sprd->md_linebytes != 2) \
292: goto hard; \
293: sp = (u_short *) sprd->md_image; \
294: IfClip( if (dst.pos.x + sizex > limx) \
295: goto hard; \
296: if (dst.pos.y + sizey > limy) \
297: sizey = limy - dst.pos.y; \
298: if (dst.pos.x < 0) \
299: goto hard; \
300: if (dst.pos.y < 0) { \
301: sizey += dst.pos.y; \
302: sp -= dst.pos.y; \
303: dp -= pr_product(dst.pos.y, vert); \
304: } \
305: if (sizex <= 0) \
306: continue; \
307: ,) \
308: if (--sizey>=0) \
309: if (dskew + sizex <= 16) { \
310: IfMask( register short mask; \
311: mask = 0x8000; \
312: sizex -= 1; \
313: mask >>= sizex; \
314: ((unsigned short) mask) >>= dskew; \
315: IfReverse(mask = ~mask;,),) \
316: do { \
317: IfMask(*(u_short *) dp IfReverse(&,|)= mask;,) \
318: *(u_short *) dp op (*sp++ >> dskew); \
319: dp += vert; \
320: } while (--sizey != -1); \
321: } \
322: else { \
323: IfMask( register long mask; \
324: mask = 0x80000000; \
325: sizex -= 1; \
326: mask >>= sizex; \
327: ((unsigned long) mask) >>= dskew; \
328: IfReverse(mask = ~mask;,),) \
329: dskew = 16 - dskew; \
330: do { \
331: IfMask(*(u_int *) dp IfReverse(&,|)= mask;,) \
332: *(u_int *) dp op (*sp++ << dskew); \
333: dp += vert; \
334: } while (--sizey != -1); \
335: } \
336: }
337:
338: #define MTRUE(a,b) a
339: #define MFALSE(a,b) b
340:
341: #define ClippedOp(mask,op,revmask) \
342: if(clip) MEMBATCH(MTRUE,mask,op,revmask) \
343: else MEMBATCH(MFALSE,mask,op,revmask)
344:
345: mem_batchrop(dst, op, src, count)
346: struct pr_prpos dst;
347: int op;
348: struct pr_prpos *src;
349: short count;
350: {
351: register u_short *sp;
352: register char *dp;
353: char *dp0;
354: register char *handy;
355: register short sizex, sizey;
356: register vert, dskew;
357: int dskew0, xoff0;
358: int errors = 0;
359: int clip, limx, limy;
360: int oppassed = op;
361:
362: /*
363: * Preliminaries: get pixrect data and image pointers; decide whether
364: * clipping. If not clipping, normalize op, else compute limits for
365: * cursors for later comparisons.
366: */
367:
368: clip = 0;
369: if (!(op & PIX_DONTCLIP)) {
370: clip = 1;
371: limx = dst.pr->pr_size.x;
372: limy = dst.pr->pr_size.y;
373: }
374: op = (op >> 1) & 0xf; /* Kill dontclip, just keep useful */
375: /*
376: * If destination is reverse video, invert function. FIXME: we dont
377: * deal with a reverse video source. Admittedly its unlikely that
378: * anyone will call batchrop with a device pixrect as source (since we
379: * copy the whole pixrect), but this is a bug.
380: */
381: if (mpr_d(dst.pr)->md_flags & MP_REVERSEVIDEO)
382: op = pr_reversedst[op];
383:
384: vert = mpr_d(dst.pr)->md_linebytes;
385: #define dprd ((struct mpr_data *)handy)
386: dprd = mpr_d(dst.pr);
387: xoff0 = dprd->md_offset.x;
388: dp0 = (char *) ((int) dprd->md_image
389: + pr_product(dprd->md_linebytes,
390: dst.pos.y + dprd->md_offset.y));
391: #undef dprd
392: restart:
393: #define spr ((struct pixrect *)handy)
394: #define sprd ((struct mpr_data *)handy)
395: switch (op) {
396: case (PIX_SRC ^ PIX_DST) >> 1:
397: ClippedOp(MFALSE, ^=, MTRUE);
398: break;
399: case PIX_SRC >> 1:
400: ClippedOp(MTRUE, |=, MTRUE);
401: break;
402: case PIX_NOT(PIX_SRC) >> 1:
403: ClippedOp(MTRUE, ^=, MFALSE);
404: break;
405: case (PIX_SRC | PIX_DST) >> 1:
406: ClippedOp(MFALSE, |=, MTRUE);
407: break;
408: case (PIX_NOT(PIX_SRC) & PIX_DST) >> 1:
409: ClippedOp(MFALSE, &=~, MTRUE);
410: break;
411: default:
412: for (; --count >= 0; src++) {
413: dst.pos.x += src->pos.x;
414: errors |= mem_rop(dst.pr, dst.pos, src->pr->pr_size,
415: oppassed, src->pr, 0, 0);
416: }
417: }
418: return errors;
419: hard:
420: if (dst.pos.x + sizex <= 0)
421: /*
422: * Completely clipped on left...
423: */
424: ;
425: else {
426: errors |= mem_rop(dst.pr, dst.pos, src->pr->pr_size,
427: oppassed, src->pr, 0, 0);
428: }
429: src++;
430: goto restart;
431: }
432:
433: /*
434: * cg2batch.c: Sun2 Color batchrop
435: */
436:
437: extern struct pixrectops mem_ops;
438:
439:
440: extern short mrc_lmasktable[];
441: extern short mrc_rmasktable[];
442:
443: #define resolution unused, 0
444:
445: cg2_batchrop(dst, op, src, count)
446: struct pr_prpos dst;
447: int op;
448: struct pr_prpos *src;
449: register int count;
450: {
451: register short sizey;
452: register int tem, w, prime, linebytes;
453: register short *bx, *leftx, *ma;
454: register struct memropc *ropregs;
455: short sizex;
456: int clip;
457: struct pixrect *pr;
458: short *ma_homey;
459: short homex, homey, limx, limy, dstx, dsty, by;
460:
461: struct cg2fb *fb;
462: struct mpr_data *md;
463: int oppassed = op;
464: int errors = 0;
465: short color;
466:
467: if (count <= 0)
468: return (0);
469:
470: /*
471: * Preliminaries: get pixrect data and frame buffer pointers; decide
472: * whether clipping. If not clipping, normalize op, else compute
473: * limits for cursors for later comparisons.
474: */
475: #define dbd ((struct cg2pr *)leftx)
476: dbd = cg2_d(dst.pr);
477: homex = dbd->cgpr_offset.x;
478: homey = dbd->cgpr_offset.y;
479: #define FB ((struct cg2fb *)leftx)
480: FB = dbd->cgpr_va;
481: fb = FB;
482: #undef dbd
483: ropregs = &FB->ropcontrol[CG2_ALLROP].ropregs;
484: if (op & PIX_DONTCLIP) {
485: op &= ~PIX_DONTCLIP;
486: clip = 0;
487: }
488: else {
489: clip = 1;
490: limx = homex + dst.pr->pr_size.x;
491: limy = homey + dst.pr->pr_size.y;
492: }
493: dstx = homex + dst.pos.x;
494: dsty = homey + dst.pos.y;
495: if (private_bgcolor < 0) {
496: FB->ppmask.reg = private_fgcolor; /* set colored text */
497: ropregs->mrc_pattern = -1;
498: FB->ppmask.reg = ~private_fgcolor;
499: ropregs->mrc_pattern = 0;
500: FB->ppmask.reg = private_czmask;
501: switch (op & 0x1E) {
502: case PIX_SRC ^ PIX_DST:
503: ropregs->mrc_op = CG_SRC & (CG_MASK ^ CG_DEST) | ~CG_SRC & CG_DEST;
504: break;
505: case PIX_NOT(PIX_DST):
506: ropregs->mrc_op = CG_SRC & (~CG_DEST) | ~CG_SRC & CG_DEST;
507: break;
508: default:
509: ropregs->mrc_op = CG_SRC & CG_MASK | ~CG_SRC & CG_DEST;
510: break;
511: }
512: }
513: else {
514: FB->ppmask.reg = private_fgcolor & private_bgcolor;
515: ropregs->mrc_op = ~0;
516: FB->ppmask.reg = ~(private_fgcolor | private_bgcolor);
517: ropregs->mrc_op = 0;
518: FB->ppmask.reg = private_fgcolor & ~private_bgcolor;
519: ropregs->mrc_op = CG_SRC;
520: FB->ppmask.reg = ~private_fgcolor & private_bgcolor;
521: ropregs->mrc_op = ~CG_SRC;
522: FB->ppmask.reg = private_czmask;
523: }
524: FB->status.reg.ropmode = PWWWRD;
525: linebytes = cg2_linebytes(FB, PWWWRD);
526: #undef FB
527:
528: for (; --count >= 0; src++) {
529: /*
530: * Update destination x and y by pre-advance amount. If no pixrect
531: * for this, then skip to next.
532: */
533: dstx += src->pos.x;
534: pr = src->pr;
535: if (pr == 0)
536: continue;
537: sizex = pr->pr_size.x;
538: sizey = pr->pr_size.y;
539: md = mpr_d(pr);
540: ma = md->md_image;
541:
542: /*
543: * Grab sizes and address of image. If clipping (rare case
544: * hopefully) compare cursors against limits.
545: */
546: by = dsty;
547: tem = 0;
548: if (clip) {
549: if (dstx + sizex > limx)
550: sizex = limx - dstx;
551: if (dsty + sizey > limy)
552: sizey = limy - dsty;
553: if (dsty < homey) { /* works if pr_depth = 1! */
554: tem = homey - dsty;
555: by += tem;
556: ma += pr_product(tem, (md->md_linebytes >> 1));
557: sizey -= tem;
558: tem = 0;
559: }
560: if (dstx < homex) {
561: tem = homex - dstx;
562: ma += tem >> 4;
563: sizex -= tem;
564: }
565: if (sizex <= 0)
566: continue;
567: }
568:
569: /*
570: * Hard case: characters greater than 16 wide.
571: */
572: ma_homey = ma;
573:
574: /* set the ROP chip word width and opcount */
575:
576: w = cg2_prskew(dstx); /* source skew is 0 */
577: ropregs->mrc_shift = (w & 0xF) | (1 << 8);
578: prime = !w;
579: w = (sizex + w + (tem & 0xF) - 1) >> 4;
580: ropregs->mrc_width = w;
581: ropregs->mrc_opcount = w;
582:
583: /* set the ROP chip end masks */
584:
585: ropregs->mrc_mask1 =
586: mrc_lmasktable[(tem += dstx) & 0xf];
587: ropregs->mrc_mask2 =
588: mrc_rmasktable[(sizex + tem - 1) & 0xf];
589:
590: leftx = cg2_ropwordaddr(fb, 0, tem, by);
591: tem = md->md_linebytes;
592: if (--sizey >= 0)
593: if (w) {
594: w++;
595: do {
596: register short i = w;
597: ma = ma_homey;
598: bx = leftx;
599: if (prime)
600: ropregs->mrc_source1 = *ma++;
601: while (i--)
602: *bx++ = *ma++;
603: (char *) ma_homey += tem;
604: (char *) leftx += linebytes;
605: } while (--sizey != -1);
606: }
607: else {
608: bx = leftx;
609: ma = ma_homey;
610: if (prime) {
611: ma++;
612: do {
613: ma--;
614: ropregs->mrc_source1 = *ma++;
615: *bx = *ma;
616: (char *) ma += tem;
617: (char *) bx += linebytes;
618: } while (--sizey != -1);
619: }
620: else
621: do {
622: *bx = *ma;
623: (char *) ma += tem;
624: (char *) bx += linebytes;
625: } while (--sizey != -1);
626: }
627: }
628:
629: return (errors);
630: }
631:
632: #endif sun
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.