diff options
Diffstat (limited to 'afb')
-rw-r--r-- | afb/README | 10 | ||||
-rw-r--r-- | afb/Xdaniver.doc | 218 | ||||
-rw-r--r-- | afb/afb.h | 1316 | ||||
-rw-r--r-- | afb/afbbitblt.c | 474 | ||||
-rw-r--r-- | afb/afbblt.c | 559 | ||||
-rw-r--r-- | afb/afbbres.c | 321 | ||||
-rw-r--r-- | afb/afbbresd.c | 212 | ||||
-rw-r--r-- | afb/afbbstore.c | 152 | ||||
-rw-r--r-- | afb/afbclip.c | 245 | ||||
-rw-r--r-- | afb/afbcmap.c | 121 | ||||
-rw-r--r-- | afb/afbfillarc.c | 355 | ||||
-rw-r--r-- | afb/afbfillrct.c | 293 | ||||
-rw-r--r-- | afb/afbfillsp.c | 1127 | ||||
-rw-r--r-- | afb/afbfont.c | 75 | ||||
-rw-r--r-- | afb/afbgc.c | 707 | ||||
-rw-r--r-- | afb/afbgetsp.c | 163 | ||||
-rw-r--r-- | afb/afbhrzvert.c | 207 | ||||
-rw-r--r-- | afb/afbimage.c | 297 | ||||
-rw-r--r-- | afb/afbimggblt.c | 466 | ||||
-rw-r--r-- | afb/afbline.c | 702 | ||||
-rw-r--r-- | afb/afbmisc.c | 92 | ||||
-rw-r--r-- | afb/afbpixmap.c | 292 | ||||
-rw-r--r-- | afb/afbply1rct.c | 296 | ||||
-rw-r--r-- | afb/afbplygblt.c | 457 | ||||
-rw-r--r-- | afb/afbpntarea.c | 653 | ||||
-rw-r--r-- | afb/afbpntwin.c | 124 | ||||
-rw-r--r-- | afb/afbpolypnt.c | 145 | ||||
-rw-r--r-- | afb/afbpushpxl.c | 256 | ||||
-rw-r--r-- | afb/afbscrinit.c | 244 | ||||
-rw-r--r-- | afb/afbsetsp.c | 265 | ||||
-rw-r--r-- | afb/afbtegblt.c | 584 | ||||
-rw-r--r-- | afb/afbtile.c | 857 | ||||
-rw-r--r-- | afb/afbwindow.c | 316 | ||||
-rw-r--r-- | afb/afbzerarc.c | 206 |
34 files changed, 12807 insertions, 0 deletions
diff --git a/afb/README b/afb/README new file mode 100644 index 000000000..5c9586013 --- /dev/null +++ b/afb/README @@ -0,0 +1,10 @@ + +All stuff in this directory is based on Xdaniver (read Xdaniver.doc). + +Actually this is the same code as in the ilbm directory, except that here the +conversion from normal bitplanes to interleaved bitplanes didn't happen. + +-- +Geert Uytterhoeven Geert.Uytterhoeven@cs.kuleuven.ac.be +Wavelets, Linux/m68k on Amiga http://www.cs.kuleuven.ac.be/~geert/ +Department of Computer Science -- Katholieke Universiteit Leuven -- Belgium diff --git a/afb/Xdaniver.doc b/afb/Xdaniver.doc new file mode 100644 index 000000000..1c8ad5ad4 --- /dev/null +++ b/afb/Xdaniver.doc @@ -0,0 +1,218 @@ + +What is it? +----------- + +Xdaniver is a fast, colour X11R6 server for the Amiga's custom chip set +under NetBSD 1.0 and NetBSD-current, supporting all the Amiga's display +depths from 1 to 4 (upto 16 colours) on ECS machines and 1 to 8 (upto 256 +colours) on AGA machines (though, not all resolutions are available, see +General Information below). + +Xdaniver is designed to be a drop-in replacement for the Xmono server provided +with the X11R6 binary distribution supplied by Bernd Ernesti available from +ftp.uni-regensburg.de or one of its mirrors. + +Unlike previous colour X servers for the Amiga that emulate a chunky pixel +screen in fast RAM, use the standard frame buffer drivers provided with the +X11R6 source code to draw and then use a chunky to planar conversion routine +to write the results to the screen (all very slow), Xdaniver uses a heavily +modified mono frame buffer driver to draw directly using the Amiga's planar +format. The net result is much faster drawing and support for all the Amiga's +custom display depths but, as usual, the fewer planes used, the faster the +drawing operations of the X server. Even so, on my A1200 with a 33Mhz 68030, +I'm getting reasonable performance when using 8 bit planes in Dbl NTSC mode. + +Installation +------------ + +You will need to have first obtained and installed the X11R6 binary +distribution available from ftp.uni-regensburg.de in +/pub/NetBSD-Amiga/contrib/X11 or one of its mirrors. Xdaniver has been +compiled to expect font and configuration files sitting under +/usr/local/X11R6, if your setup is different you will need to provide a +symbolic link from /usr/local/X11R6 to where your tree resides or supply +several command line flags to the server. + +To get Xdaniver running as the default X server, copy the uncompressed binary +into /usr/local/X11R6/bin, remove the current X file from that directory +(which is a symbolic link to Xmono) and replace it with a link to Xdaniver: + + gzip -d < X11R6.Xdaniver.1.01.tar.gz | tar xvf - + mv Xdaniver /usr/local/X11R6/bin + cd /usr/local/X11R6/bin + rm X + ln -s Xdaniver X + +Note that on some setups, the devices /dev/kbd, /dev/mouse and /dev/view?? +have been created to be accessable only by superuser; Xdaniver needs to open +these devices. To workaround this problem, log on as superuser and then +either make Xdaniver setuid root: + + chown root Xdaniver + chmod 4755 Xdaniver + +or give everyone access the devices: + + chmod 666 /dev/kbd /dev/mouse /dev/view?? + +the latter option is a possible cause of a security hole if your machine is +ever used multi-user. + +General Information +------------------- + +The default resolution of the server is 700x430 and the default depth 4. AGA +users might what to increase the display depth by editing the startx script +and providing a -depth <depth> argument to Xdaniver on the xinit line of the +script. As always, the lower the depth, the faster the drawing and window +manipulation of the server. + +The resolution can be altered similarly by suppling -width <width> and +-height <height> arguments to the server. + +The NetBSD kernel selects actual screen modes by picking a mode who's +natural, non-overscanned size best-fits the requested resolution. +Unfortunately, for AGA users, the 1.0 kernel only has support for the +Dbl-NTSC AGA display mode and only this mode has support for depths greater +than 4. The NetBSD-current (work-in-progress) kernel also has support for +Dbl-PAL but still no support for the Super72 or other super-hires modes +(perhaps some kind, kernel-hacker could add support for them ?). + +If you have a 2 button mouse (like me) you might want to try and use the 3 +button mouse emulation. On other systems, it is usual for the left and right +buttons to be provided and emulate the middle button by pressing both +buttons together, however, the middle button is tends to be used more than +the right button so I have provided two options: + +-emulateright (or -3), the two physical mouse buttons act as left and middle +and pressing them both together emulates the right button. + +-emulatemiddle (or -2), the two physical mouse buttons act as left and right +and pressing them both together emulated the middle button. + +When using screen depths of less than 6 (4 is the maximum for ECS machines) +the lack of possible colours on screen at once causes problems for many X +applications. Specifying -cc 2 as a command line argument to Xdaniver +causes the server to switch the default visual type from PsuedoColor to +StaticColor; to put it simply, the server prefills the colormap with a +selection of 16 colours (depth 4) and when an application asks for a +particular colour, its gets allocated one that is closest to one from the +selection of 16. This removes the 'WARNING: Cannot allocate colormap entry +for "XXX"' errors but at the expense of applications not being able to get +the precise colour they wanted. Also, some badly written X applications fail +altogether when presented with a StaticColor visual. + +Bugs/Limitations +---------------- + +The limited choice of display resolutions for AGA/ECS machines is a real +pain - requires a kernel change to fix. Worse still, the kernel specifies +the maximum overscan resolution on the Dbl-NTSC to be 724x482 but selecting +anything more than 702x430 on my machine causes the screen either sheer +diagonally (as if the bytes per row calculation in Xdaniver or the kernel is +wrong) or completely loose sync (suggesting a custom chip register sync +calculation bug). As other, non-aga modes aren't affected when selection +overscan both problems seem to point to a kernel driver bug. Also, depths +greater than 4 for AGA users are only supported by the kernel in the Dbl-NTSC +mode (and Dbl-PAL with the current-NetBSD kernel). + +I know of one bug so-far (there will be more), The PutImage request of an XY +format image expects the bitplane order to be the reverse of that specified +in the X protocol but since virtually all applications use the Z (chunky) +format, you are unlikely to come across this problem. + +The PutImage request of Z format images is a little slow - when I have time +I'll try and add one of the fast assembly chunky-to-planar routines developed +for doom style games/demos. Unfortunately, the current crop all require a +picture size that is a multiple of 32 pixels and so cannot be used out-of-the- +box. + +Some extra performance could easily be squeezed out of the terminal font +drawing code (used by xterm) - when I have time I'll add the code. + +The Amiga's blitter and sprites are totally unused and will remain so +until/if someone else adds support to the kernel. The blitter would help +speed up screen scrolling and window manipulation and sprite support could +be used for the X pointer shape (if small enough) which would speed up all +drawing operations (no need to remove the software based pointer shape +first, draw, then replace the pointer shape). + +I removed the X image extension (XIE) from the X server as it increased the +size of the binary by some 400k. I haven't come across any applications that +need it yet (I haven't been looking!) so if you need the extension for some +reason send me e-mail and I'll build a server with the extension included. + +The 3 button mouse emulation is very simple - to emulate the 3rd button you +have to press both button precisely at the same moment - I've got quite good +at it now. When I have some spare time I'll add a timer so you will have a +few milli-seconds between one button being pressed and the next and it still +being registered as the emulated button. + +AGA users don't forget to provide the -A flag to loadbsd to enable the one +AGA mode in the 1.0 kernel but only if you have a VGA, multisync or dual-scan +monitor, of course ! + +Xdaniver has been tested on: + +A1200, 33Mhz 68030, 8Mb RAM and NetBSD 1.0 by myself. +A4000/40, 12Mb RAM and NetBSD 1.0 by Andreas Holzhammer. +A3000, 12Mb RAM and NetBSD 1.0 by Charlie Root, Stuart Park and others. +A3000, 25Mhz 68040, 18Mb RAM and NetBSD-current by Michael K. Sanders. +A2000, 8Mb RAM and NetBSD (version unknown) by Hubert Feyrer. + +Release and Bug Fix History +--------------------------- + +1.0 - First release + +1.01 Bugs fixed: + - Narrow (<32 pixels) Z format GetImage requests corrupted the stack + and could cause the server to core dump. (Xpaint caused this problem) + - Drawing dots (PolyPoint request) into a clipped window caused a + c pointer to go out of range, causing a core dump (xv showed this + problem). + + New features: + - Simple 3 button mouse emulation using a 2 button mouse; specify + -emulate_middle (or -2) or -emulate_right (or -3) on the server's + command line and press both mouse buttons together emulate the 'missing' + button. + - Basic beep sound support added by sending bell characters to the + console. + - Source code released. + +Disclaimer and Copyright Notices +-------------------------------- + +Multi-depth planar frame buffer code: +Copyright (c) 1995 by Daniver Limited. + +Large portions: +Copyright (c) 1994 by Eduardo Horvath. +Copyright (c) 1987-1995 by the Regents of the University of California. +Copyright (c) 1987 by Sun Microsystems, Inc. Mountain View, CA. +Copyright (c) 1987-1995 by X Consortium. +Copyright (c) 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. +Copyright (c) 1989 Network Computing Devices, Inc., Mountain View, California. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies. The Daniver Limited, +the above companies and individuals makes no representations about the +suitability of this software for any purpose. It is provided "as is" without +express or implied warranty. + +Credits +------- + +Thanks to Bernd Ernesti for making the operating system server source code +available for others to use and Eduardo Horvath and Andy Heffernan, who (I +think) did the original Xmono server port. + +Also, many thanks to the first brave users who tested Xdaniver for me on other +Amiga setups and found a few bugs in the process. + +Gary Henderson. + +Daytime: garyh@wet.sbi.com +Home: gary@daniver.demon.co.uk diff --git a/afb/afb.h b/afb/afb.h new file mode 100644 index 000000000..d05d0edfc --- /dev/null +++ b/afb/afb.h @@ -0,0 +1,1316 @@ +/* $XFree86: xc/programs/Xserver/afb/afb.h,v 3.8 2001/10/28 03:32:57 tsi Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afb.h,v 5.31 94/04/17 20:28:15 dpw Exp $ */ +/* Monochrome Frame Buffer definitions + written by drewry, september 1986 +*/ + +#include "pixmap.h" +#include "region.h" +#include "gc.h" +#include "colormap.h" +#include "miscstruct.h" +#include "mibstore.h" +#include "mfb.h" + +extern int afbInverseAlu[]; +extern int afbScreenPrivateIndex; +/* warning: PixelType definition duplicated in maskbits.h */ +#ifndef PixelType +#define PixelType CARD32 +#endif /* PixelType */ + +#define AFB_MAX_DEPTH 8 + +/* afbbitblt.c */ + +extern void afbDoBitblt( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); + +extern RegionPtr afbBitBlt( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + GCPtr /*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*width*/, + int /*height*/, + int /*dstx*/, + int /*dsty*/, + void (*doBitBlt)( +#if NeedNestedPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif + ), + unsigned long /*planemask*/ +#endif +); + +extern RegionPtr afbCopyArea( +#if NeedFunctionPrototypes + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + GCPtr/*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*width*/, + int /*height*/, + int /*dstx*/, + int /*dsty*/ +#endif +); + +extern RegionPtr afbCopyPlane( +#if NeedFunctionPrototypes + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + GCPtr/*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*width*/, + int /*height*/, + int /*dstx*/, + int /*dsty*/, + unsigned long /*plane*/ +#endif +); + +extern void afbCopy1ToN( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* afbbltC.c */ + +extern void afbDoBitbltCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* afbbltCI.c */ + +extern void afbDoBitbltCopyInverted( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* afbbltG.c */ + +extern void afbDoBitbltGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* afbbltO.c */ + +extern void afbDoBitbltOr( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* afbbltX.c */ + +extern void afbDoBitbltXor( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* afbbres.c */ + +extern void afbBresS( +#if NeedFunctionPrototypes + PixelType * /*addrl*/, + int /*nlwidth*/, + int /*sizeDst*/, + int /*depthDst*/, + int /*signdx*/, + int /*signdy*/, + int /*axis*/, + int /*x1*/, + int /*y1*/, + int /*e*/, + int /*e1*/, + int /*e2*/, + int /*len*/, + unsigned char * /*rrops*/ +#endif +); +/* afbbresd.c */ + +extern void afbBresD( +#if NeedFunctionPrototypes + int * /*pdashIndex*/, + unsigned char * /*pDash*/, + int /*numInDashList*/, + int * /*pdashOffset*/, + int /*isDoubleDash*/, + PixelType * /*addrl*/, + int /*nlwidth*/, + int /*sizeDst*/, + int /*depthDst*/, + int /*signdx*/, + int /*signdy*/, + int /*axis*/, + int /*x1*/, + int /*y1*/, + int /*e*/, + int /*e1*/, + int /*e2*/, + int /*len*/, + unsigned char * /*rrops*/, + unsigned char * /*bgrrops*/ +#endif +); +/* afbbstore.c */ + +extern void afbSaveAreas( +#if NeedFunctionPrototypes + PixmapPtr /*pPixmap*/, + RegionPtr /*prgnSave*/, + int /*xorg*/, + int /*yorg*/, + WindowPtr /*pWin*/ +#endif +); + +extern void afbRestoreAreas( +#if NeedFunctionPrototypes + PixmapPtr /*pPixmap*/, + RegionPtr /*prgnRestore*/, + int /*xorg*/, + int /*yorg*/, + WindowPtr /*pWin*/ +#endif +); +/* afbclip.c */ + +extern RegionPtr afbPixmapToRegion( +#if NeedFunctionPrototypes + PixmapPtr /*pPix*/ +#endif +); + +/* afbcmap.c */ + +extern int afbListInstalledColormaps( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + Colormap * /*pmaps*/ +#endif +); + +extern void afbInstallColormap( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/ +#endif +); + +extern void afbUninstallColormap( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/ +#endif +); + +extern void afbResolveColor( +#if NeedFunctionPrototypes + unsigned short * /*pred*/, + unsigned short * /*pgreen*/, + unsigned short * /*pblue*/, + VisualPtr /*pVisual*/ +#endif +); + +extern Bool afbInitializeColormap( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/ +#endif +); + +extern int afbExpandDirectColors( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/, + int /*ndefs*/, + xColorItem * /*indefs*/, + xColorItem * /*outdefs*/ +#endif +); + +extern Bool afbCreateDefColormap( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/ +#endif +); + +extern Bool afbSetVisualTypes( +#if NeedFunctionPrototypes + int /*depth*/, + int /*visuals*/, + int /*bitsPerRGB*/ +#endif +); + +extern Bool afbInitVisuals( +#if NeedFunctionPrototypes + VisualPtr * /*visualp*/, + DepthPtr * /*depthp*/, + int * /*nvisualp*/, + int * /*ndepthp*/, + int * /*rootDepthp*/, + VisualID * /*defaultVisp*/, + unsigned long /*sizes*/, + int /*bitsPerRGB*/ +#endif +); + +/* afbfillarc.c */ + +extern void afbPolyFillArcSolid( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +#endif +); +/* afbfillrct.c */ + +extern void afbPolyFillRect( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nrectFill*/, + xRectangle * /*prectInit*/ +#endif +); + +/* afbply1rct.c */ +extern void afbFillPolygonSolid( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*shape*/, + int /*count*/, + DDXPointPtr /*ptsIn*/ +#endif +); + +/* afbfillsp.c */ + +extern void afbSolidFS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +extern void afbStippleFS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +extern void afbTileFS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +extern void afbUnnaturalTileFS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +extern void afbUnnaturalStippleFS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +extern void afbOpaqueStippleFS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +extern void afbUnnaturalOpaqueStippleFS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +/* afbfont.c */ + +extern Bool afbRealizeFont( +#if NeedFunctionPrototypes + ScreenPtr /*pscr*/, + FontPtr /*pFont*/ +#endif +); + +extern Bool afbUnrealizeFont( +#if NeedFunctionPrototypes + ScreenPtr /*pscr*/, + FontPtr /*pFont*/ +#endif +); +/* afbgc.c */ + +extern Bool afbCreateGC( +#if NeedFunctionPrototypes + GCPtr /*pGC*/ +#endif +); + +extern void afbValidateGC( +#if NeedFunctionPrototypes + GCPtr /*pGC*/, + unsigned long /*changes*/, + DrawablePtr /*pDrawable*/ +#endif +); + +extern void afbDestroyGC( +#if NeedFunctionPrototypes + GCPtr /*pGC*/ +#endif +); + +extern void afbReduceRop( +#if NeedFunctionPrototypes + int /*alu*/, + Pixel /*src*/, + unsigned long /*planemask*/, + int /*depth*/, + unsigned char * /*rrops*/ +#endif +); + +extern void afbReduceOpaqueStipple ( +#if NeedFunctionPrototypes + Pixel /*fg*/, + Pixel /*bg*/, + unsigned long /*planemask*/, + int /*depth*/, + unsigned char * /*rrops*/ +#endif +); + +extern void afbComputeCompositeClip( +#if NeedFunctionPrototypes + GCPtr /*pGC*/, + DrawablePtr /*pDrawable*/ +#endif +); + +/* afbgetsp.c */ + +extern void afbGetSpans( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*wMax*/, + DDXPointPtr /*ppt*/, + int * /*pwidth*/, + int /*nspans*/, + char * /*pdstStart*/ +#endif +); +/* afbhrzvert.c */ + +extern void afbHorzS( +#if NeedFunctionPrototypes + PixelType * /*addrl*/, + int /*nlwidth*/, + int /*sizeDst*/, + int /*depthDst*/, + int /*x1*/, + int /*y1*/, + int /*len*/, + unsigned char * /*rrops*/ +#endif +); + +extern void afbVertS( +#if NeedFunctionPrototypes + PixelType * /*addrl*/, + int /*nlwidth*/, + int /*sizeDst*/, + int /*depthDst*/, + int /*x1*/, + int /*y1*/, + int /*len*/, + unsigned char * /*rrops*/ +#endif +); +/* afbigbblak.c */ + +extern void afbImageGlyphBlt ( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +#endif +); +/* afbigbwht.c */ + +/* afbimage.c */ + +extern void afbPutImage( +#if NeedFunctionPrototypes + DrawablePtr /*dst*/, + GCPtr /*pGC*/, + int /*depth*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + int /*leftPad*/, + int /*format*/, + char * /*pImage*/ +#endif +); + +extern void afbGetImage( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*sx*/, + int /*sy*/, + int /*w*/, + int /*h*/, + unsigned int /*format*/, + unsigned long /*planeMask*/, + char * /*pdstLine*/ +#endif +); +/* afbline.c */ + +extern void afbLineSS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/ +#endif +); + +extern void afbLineSD( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/ +#endif +); + +/* afbmisc.c */ + +extern void afbQueryBestSize( +#if NeedFunctionPrototypes + int /*class*/, + unsigned short * /*pwidth*/, + unsigned short * /*pheight*/, + ScreenPtr /*pScreen*/ +#endif +); +/* afbpntarea.c */ + +extern void afbSolidFillArea( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + unsigned char * /*rrops*/ +#endif +); + +extern void afbStippleAreaPPW( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + PixmapPtr /*pstipple*/, + unsigned char * /*rrops*/ +#endif +); +extern void afbStippleArea( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + PixmapPtr /*pstipple*/, + int /*xOff*/, + int /*yOff*/, + unsigned char * /*rrops*/ +#endif +); +/* afbplygblt.c */ + +extern void afbPolyGlyphBlt( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +#endif +); + +/* afbpixmap.c */ + +extern PixmapPtr afbCreatePixmap( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + int /*width*/, + int /*height*/, + int /*depth*/ +#endif +); + +extern Bool afbDestroyPixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pPixmap*/ +#endif +); + +extern PixmapPtr afbCopyPixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pSrc*/ +#endif +); + +extern void afbPadPixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pPixmap*/ +#endif +); + +extern void afbXRotatePixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pPix*/, + int /*rw*/ +#endif +); + +extern void afbYRotatePixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pPix*/, + int /*rh*/ +#endif +); + +extern void afbCopyRotatePixmap( +#if NeedFunctionPrototypes + PixmapPtr /*psrcPix*/, + PixmapPtr * /*ppdstPix*/, + int /*xrot*/, + int /*yrot*/ +#endif +); +extern void afbPaintWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/, + RegionPtr /*pRegion*/, + int /*what*/ +#endif +); +/* afbpolypnt.c */ + +extern void afbPolyPoint( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + xPoint * /*pptInit*/ +#endif +); +/* afbpushpxl.c */ + +extern void afbPushPixels( +#if NeedFunctionPrototypes + GCPtr /*pGC*/, + PixmapPtr /*pBitMap*/, + DrawablePtr /*pDrawable*/, + int /*dx*/, + int /*dy*/, + int /*xOrg*/, + int /*yOrg*/ +#endif +); +/* afbscrclse.c */ + +extern Bool afbCloseScreen( +#if NeedFunctionPrototypes + int /*index*/, + ScreenPtr /*pScreen*/ +#endif +); +/* afbscrinit.c */ + +extern Bool afbAllocatePrivates( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + int * /*pWinIndex*/, + int * /*pGCIndex*/ +#endif +); + +extern Bool afbScreenInit( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + pointer /*pbits*/, + int /*xsize*/, + int /*ysize*/, + int /*dpix*/, + int /*dpiy*/, + int /*width*/ +#endif +); + +extern PixmapPtr afbGetWindowPixmap( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/ +#endif +); + +extern void afbSetWindowPixmap( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/, + PixmapPtr /*pPix*/ +#endif +); + +/* afbseg.c */ + +extern void afbSegmentSS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSeg*/ +#endif +); + +extern void afbSegmentSD( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSeg*/ +#endif +); +/* afbsetsp.c */ + +extern void afbSetScanline( +#if NeedFunctionPrototypes + int /*y*/, + int /*xOrigin*/, + int /*xStart*/, + int /*xEnd*/, + PixelType * /*psrc*/, + int /*alu*/, + PixelType * /*pdstBase*/, + int /*widthDst*/, + int /*sizeDst*/, + int /*depthDst*/, + int /*sizeSrc*/ +#endif +); + +extern void afbSetSpans( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + char * /*psrc*/, + DDXPointPtr /*ppt*/, + int * /*pwidth*/, + int /*nspans*/, + int /*fSorted*/ +#endif +); +/* afbtegblt.c */ + +extern void afbTEGlyphBlt( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +#endif +); +/* afbtileC.c */ + +extern void afbTileAreaPPWCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + int /*alu*/, + PixmapPtr /*ptile*/, + unsigned long /*planemask*/ +#endif +); +/* afbtileG.c */ + +extern void afbTileAreaPPWGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + int /*alu*/, + PixmapPtr /*ptile*/, + unsigned long /*planemask*/ +#endif +); + +extern void afbTileAreaCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + int /*alu*/, + PixmapPtr /*ptile*/, + int /*xOff*/, + int /*yOff*/, + unsigned long /*planemask*/ +#endif +); +/* afbtileG.c */ + +extern void afbTileAreaGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + int /*alu*/, + PixmapPtr /*ptile*/, + int /*xOff*/, + int /*yOff*/, + unsigned long /*planemask*/ +#endif +); + +extern void afbOpaqueStippleAreaPPWCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + int /*alu*/, + PixmapPtr /*ptile*/, + unsigned char */*rropsOS*/, + unsigned long /*planemask*/ +#endif +); +/* afbtileG.c */ + +extern void afbOpaqueStippleAreaPPWGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + int /*alu*/, + PixmapPtr /*ptile*/, + unsigned char */*rropsOS*/, + unsigned long /*planemask*/ +#endif +); + +extern void afbOpaqueStippleAreaCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + int /*alu*/, + PixmapPtr /*ptile*/, + int /*xOff*/, + int /*yOff*/, + unsigned char */*rropsOS*/, + unsigned long /*planemask*/ +#endif +); +/* afbtileG.c */ + +extern void afbOpaqueStippleAreaGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + int /*nbox*/, + BoxPtr /*pbox*/, + int /*alu*/, + PixmapPtr /*ptile*/, + int /*xOff*/, + int /*yOff*/, + unsigned char */*rropsOS*/, + unsigned long /*planemask*/ +#endif +); + +/* afbwindow.c */ + +extern Bool afbCreateWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/ +#endif +); + +extern Bool afbDestroyWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/ +#endif +); + +extern Bool afbMapWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWindow*/ +#endif +); + +extern Bool afbPositionWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/, + int /*x*/, + int /*y*/ +#endif +); + +extern Bool afbUnmapWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWindow*/ +#endif +); + +extern void afbCopyWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/, + DDXPointRec /*ptOldOrg*/, + RegionPtr /*prgnSrc*/ +#endif +); + +extern Bool afbChangeWindowAttributes( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/, + unsigned long /*mask*/ +#endif +); +/* afbzerarc.c */ + +extern void afbZeroPolyArcSS( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +#endif +); + +/* + private field of pixmap + pixmap.devPrivate = (PixelType *)pointer_to_bits + pixmap.devKind = width_of_pixmap_in_bytes + + private field of screen + a pixmap, for which we allocate storage. devPrivate is a pointer to +the bits in the hardware framebuffer. note that devKind can be poked to +make the code work for framebuffers that are wider than their +displayable screen (e.g. the early vsII, which displayed 960 pixels +across, but was 1024 in the hardware.) + + private field of GC +*/ + +typedef struct { + unsigned char rrops[AFB_MAX_DEPTH]; /* reduction of rasterop to 1 of 3 */ + unsigned char rropOS[AFB_MAX_DEPTH]; /* rop for opaque stipple */ +} afbPrivGC; +typedef afbPrivGC *afbPrivGCPtr; + +extern int afbGCPrivateIndex; /* index into GC private array */ +extern int afbWindowPrivateIndex; /* index into Window private array */ +#ifdef PIXMAP_PER_WINDOW +extern int frameWindowPrivateIndex; /* index into Window private array */ +#endif + +#define afbGetGCPrivate(pGC) \ + ((afbPrivGC *)((pGC)->devPrivates[afbGCPrivateIndex].ptr)) + +/* private field of window */ +typedef struct { + unsigned char fastBorder; /* non-zero if border tile is 32 bits wide */ + unsigned char fastBackground; + unsigned short unused; /* pad for alignment with Sun compiler */ + DDXPointRec oldRotate; + PixmapPtr pRotatedBackground; + PixmapPtr pRotatedBorder; +} afbPrivWin; + +/* Common macros for extracting drawing information */ + +#define afbGetTypedWidth(pDrawable,wtype)( \ + (((pDrawable)->type == DRAWABLE_WINDOW) ? \ + (int)(((PixmapPtr)((pDrawable)->pScreen->devPrivates[afbScreenPrivateIndex].ptr))->devKind) : \ + (int)(((PixmapPtr)pDrawable)->devKind)) / sizeof (wtype)) + +#define afbGetByteWidth(pDrawable) afbGetTypedWidth(pDrawable, unsigned char) + +#define afbGetPixelWidth(pDrawable) afbGetTypedWidth(pDrawable, PixelType) + +#define afbGetTypedWidthAndPointer(pDrawable, width, pointer, wtype, ptype) {\ + PixmapPtr _pPix; \ + if ((pDrawable)->type == DRAWABLE_WINDOW) \ + _pPix = (PixmapPtr)(pDrawable)->pScreen->devPrivates[afbScreenPrivateIndex].ptr; \ + else \ + _pPix = (PixmapPtr)(pDrawable); \ + (pointer) = (ptype *) _pPix->devPrivate.ptr; \ + (width) = ((int) _pPix->devKind) / sizeof (wtype); \ +} + +#define afbGetPixelWidthSizeDepthAndPointer(pDrawable, width, size, dep, pointer) {\ + PixmapPtr _pPix; \ + if ((pDrawable)->type == DRAWABLE_WINDOW) \ + _pPix = (PixmapPtr)(pDrawable)->pScreen->devPrivates[afbScreenPrivateIndex].ptr; \ + else \ + _pPix = (PixmapPtr)(pDrawable); \ + (pointer) = (PixelType *)_pPix->devPrivate.ptr; \ + (width) = ((int)_pPix->devKind) / sizeof (PixelType); \ + (size) = (width) * _pPix->drawable.height; \ + (dep) = _pPix->drawable.depth; \ +} + +#define afbGetByteWidthAndPointer(pDrawable, width, pointer) \ + afbGetTypedWidthAndPointer(pDrawable, width, pointer, unsigned char, unsigned char) + +#define afbGetPixelWidthAndPointer(pDrawable, width, pointer) \ + afbGetTypedWidthAndPointer(pDrawable, width, pointer, PixelType, PixelType) + +#define afbGetWindowTypedWidthAndPointer(pWin, width, pointer, wtype, ptype) {\ + PixmapPtr _pPix = (PixmapPtr)(pWin)->drawable.pScreen->devPrivates[afbScreenPrivateIndex].ptr; \ + (pointer) = (ptype *) _pPix->devPrivate.ptr; \ + (width) = ((int) _pPix->devKind) / sizeof (wtype); \ +} + +#define afbGetWindowPixelWidthAndPointer(pWin, width, pointer) \ + afbGetWindowTypedWidthAndPointer(pWin, width, pointer, PixelType, PixelType) + +#define afbGetWindowByteWidthAndPointer(pWin, width, pointer) \ + afbGetWindowTypedWidthAndPointer(pWin, width, pointer, char, char) + +/* afb uses the following macros to calculate addresses in drawables. + * To support banked framebuffers, the macros come in four flavors. + * All four collapse into the same definition on unbanked devices. + * + * afbScanlineFoo - calculate address and do bank switching + * afbScanlineFooNoBankSwitch - calculate address, don't bank switch + * afbScanlineFooSrc - calculate address, switch source bank + * afbScanlineFooDst - calculate address, switch destination bank + */ + +/* The NoBankSwitch versions are the same for banked and unbanked cases */ + +#define afbScanlineIncNoBankSwitch(_ptr, _off) _ptr += (_off) +#define afbScanlineOffsetNoBankSwitch(_ptr, _off) ((_ptr) + (_off)) +#define afbScanlineDeltaNoBankSwitch(_ptr, _y, _w) \ + afbScanlineOffsetNoBankSwitch(_ptr, (_y) * (_w)) +#define afbScanlineNoBankSwitch(_ptr, _x, _y, _w) \ + afbScanlineOffsetNoBankSwitch(_ptr, (_y) * (_w) + ((_x) >> MFB_PWSH)) + +#ifdef MFB_LINE_BANK + +#include "afblinebank.h" /* get macro definitions from this file */ + +#else /* !MFB_LINE_BANK - unbanked case */ + +#define afbScanlineInc(_ptr, _off) afbScanlineIncNoBankSwitch(_ptr, _off) +#define afbScanlineIncSrc(_ptr, _off) afbScanlineInc(_ptr, _off) +#define afbScanlineIncDst(_ptr, _off) afbScanlineInc(_ptr, _off) + +#define afbScanlineOffset(_ptr, _off) afbScanlineOffsetNoBankSwitch(_ptr, _off) +#define afbScanlineOffsetSrc(_ptr, _off) afbScanlineOffset(_ptr, _off) +#define afbScanlineOffsetDst(_ptr, _off) afbScanlineOffset(_ptr, _off) + +#define afbScanlineSrc(_ptr, _x, _y, _w) afbScanline(_ptr, _x, _y, _w) +#define afbScanlineDst(_ptr, _x, _y, _w) afbScanline(_ptr, _x, _y, _w) + +#define afbScanlineDeltaSrc(_ptr, _y, _w) afbScanlineDelta(_ptr, _y, _w) +#define afbScanlineDeltaDst(_ptr, _y, _w) afbScanlineDelta(_ptr, _y, _w) + +#endif /* MFB_LINE_BANK */ + +#define afbScanlineDelta(_ptr, _y, _w) \ + afbScanlineOffset(_ptr, (_y) * (_w)) + +#define afbScanline(_ptr, _x, _y, _w) \ + afbScanlineOffset(_ptr, (_y) * (_w) + ((_x) >> MFB_PWSH)) + +/* precomputed information about each glyph for GlyphBlt code. + this saves recalculating the per glyph information for each box. +*/ + +typedef struct _afbpos{ + int xpos; /* xposition of glyph's origin */ + int xchar; /* x position mod 32 */ + int leftEdge; + int rightEdge; + int topEdge; + int bottomEdge; + PixelType *pdstBase; /* longword with character origin */ + int widthGlyph; /* width in bytes of this glyph */ +} afbTEXTPOS; + +/* reduced raster ops for afb */ +#define RROP_BLACK GXclear +#define RROP_WHITE GXset +#define RROP_NOP GXnoop +#define RROP_INVERT GXinvert +#define RROP_COPY GXcopy + +/* macros for afbbitblt.c, afbfillsp.c + these let the code do one switch on the rop per call, rather + than a switch on the rop per item (span or rectangle.) +*/ + +#define fnCLEAR(src, dst) (0) +#define fnAND(src, dst) (src & dst) +#define fnANDREVERSE(src, dst) (src & ~dst) +#define fnCOPY(src, dst) (src) +#define fnANDINVERTED(src, dst) (~src & dst) +#define fnNOOP(src, dst) (dst) +#define fnXOR(src, dst) (src ^ dst) +#define fnOR(src, dst) (src | dst) +#define fnNOR(src, dst) (~(src | dst)) +#define fnEQUIV(src, dst) (~src ^ dst) +#define fnINVERT(src, dst) (~dst) +#define fnORREVERSE(src, dst) (src | ~dst) +#define fnCOPYINVERTED(src, dst) (~src) +#define fnORINVERTED(src, dst) (~src | dst) +#define fnNAND(src, dst) (~(src & dst)) +#undef fnSET +#define fnSET(src, dst) (~0) + +/* Using a "switch" statement is much faster in most cases + * since the compiler can do a look-up table or multi-way branch + * instruction, depending on the architecture. The result on + * A Sun 3/50 is at least 2.5 times faster, assuming a uniform + * distribution of RasterOp operation types. + * + * However, doing some profiling on a running system reveals + * GXcopy is the operation over 99.5% of the time and + * GXxor is the next most frequent (about .4%), so we make special + * checks for those first. + * + * Note that this requires a change to the "calling sequence" + * since we can't engineer a "switch" statement to have an lvalue. + */ +#undef DoRop +#define DoRop(result, alu, src, dst) \ +{ \ + if (alu == GXcopy) \ + result = fnCOPY (src, dst); \ + else if (alu == GXxor) \ + result = fnXOR (src, dst); \ + else \ + switch (alu) { \ + case GXclear: \ + result = fnCLEAR (src, dst); \ + break; \ + case GXand: \ + result = fnAND (src, dst); \ + break; \ + case GXandReverse: \ + result = fnANDREVERSE (src, dst); \ + break; \ + case GXandInverted: \ + result = fnANDINVERTED (src, dst); \ + break; \ + default: \ + case GXnoop: \ + result = fnNOOP (src, dst); \ + break; \ + case GXor: \ + result = fnOR (src, dst); \ + break; \ + case GXnor: \ + result = fnNOR (src, dst); \ + break; \ + case GXequiv: \ + result = fnEQUIV (src, dst); \ + break; \ + case GXinvert: \ + result = fnINVERT (src, dst); \ + break; \ + case GXorReverse: \ + result = fnORREVERSE (src, dst); \ + break; \ + case GXcopyInverted: \ + result = fnCOPYINVERTED (src, dst); \ + break; \ + case GXorInverted: \ + result = fnORINVERTED (src, dst); \ + break; \ + case GXnand: \ + result = fnNAND (src, dst); \ + break; \ + case GXset: \ + result = fnSET (src, dst); \ + break; \ + } \ +} + + +/* C expression fragments for various operations. These get passed in + * as -D's on the compile command line. See afb/Imakefile. This + * fixes XBUG 6319. + * + * This seems like a good place to point out that afb's use of the + * words black and white is an unfortunate misnomer. In afb code, black + * means zero, and white means one. + */ +#define MFB_OPEQ_WHITE |= +#define MFB_OPEQ_BLACK &=~ +#define MFB_OPEQ_INVERT ^= +#define MFB_EQWHOLEWORD_WHITE =~0 +#define MFB_EQWHOLEWORD_BLACK =0 +#define MFB_EQWHOLEWORD_INVERT ^=~0 +#define MFB_OP_WHITE /* nothing */ +#define MFB_OP_BLACK ~ + +#ifdef XFree86LOADER +#include "xf86_ansic.h" +#endif + diff --git a/afb/afbbitblt.c b/afb/afbbitblt.c new file mode 100644 index 000000000..c201099b5 --- /dev/null +++ b/afb/afbbitblt.c @@ -0,0 +1,474 @@ +/* $XFree86: xc/programs/Xserver/afb/afbbitblt.c,v 3.3 2001/10/28 03:32:57 tsi Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbbitblt.c,v 5.25 94/04/17 20:28:16 dpw Exp $ */ + +#include "X.h" +#include "Xprotostr.h" + +#include "miscstruct.h" +#include "regionstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "mi.h" + +#include "afb.h" +#include "maskbits.h" + + +static unsigned char afbRropsOS[AFB_MAX_DEPTH]; + +/* CopyArea and CopyPlane for a monchrome frame buffer + + + clip the source rectangle to the source's available bits. (this +avoids copying unnecessary pieces that will just get exposed anyway.) +this becomes the new shape of the destination. + clip the destination region to the composite clip in the +GC. this requires translating the destination region to (dstx, dsty). + build a list of source points, one for each rectangle in the +destination. this is a simple translation. + go do the multiple rectangle copies + do graphics exposures +*/ +/** Optimized for drawing pixmaps into windows, especially when drawing into + ** unobscured windows. Calls to the general-purpose region code were + ** replaced with rectangle-to-rectangle clipping comparisions. This is + ** possible, since the pixmap is a single rectangle. In an unobscured + ** window, the destination clip is also a single rectangle, and region + ** code can be avoided entirely. This is a big savings, since the region + ** code uses XAlloc() and makes many function calls. + ** + ** In addition, if source is a pixmap, there is no need to call the + ** expensive miHandleExposures() routine. Instead, we simply return NULL. + ** + ** Previously, drawing a pixmap into an unobscured window executed at least + ** 8 XAlloc()'s, 30 function calls, and hundreds of lines of code. + ** + ** Now, the same operation requires no XAlloc()'s, no region function calls, + ** and much less overhead. Nice for drawing lots of small pixmaps. + */ + +void +afbDoBitblt(pSrc, pDst, alu, prgnDst, pptSrc, planemask) + DrawablePtr pSrc, pDst; + int alu; + RegionPtr prgnDst; + DDXPointPtr pptSrc; + unsigned long planemask; +{ + switch (alu) { + case GXcopy: + afbDoBitbltCopy(pSrc, pDst, alu, prgnDst, pptSrc, planemask); + break; + case GXxor: + afbDoBitbltXor(pSrc, pDst, alu, prgnDst, pptSrc, planemask); + break; + case GXcopyInverted: + afbDoBitbltCopyInverted(pSrc, pDst, alu, prgnDst, pptSrc, planemask); + break; + case GXor: + afbDoBitbltOr(pSrc, pDst, alu, prgnDst, pptSrc, planemask); + break; + default: + afbDoBitbltGeneral(pSrc, pDst, alu, prgnDst, pptSrc, planemask); + break; + } +} + +RegionPtr +afbCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, + dstx, dsty) + DrawablePtr pSrcDrawable; + DrawablePtr pDstDrawable; + GC *pGC; + int srcx, srcy; + int width, height; + int dstx, dsty; +{ + void (*doBitBlt)(); + + switch (pGC->alu) { + case GXcopy: + doBitBlt = afbDoBitbltCopy; + break; + case GXxor: + doBitBlt = afbDoBitbltXor; + break; + case GXcopyInverted: + doBitBlt = afbDoBitbltCopyInverted; + break; + case GXor: + doBitBlt = afbDoBitbltOr; + break; + default: + doBitBlt = afbDoBitbltGeneral; + break; + } + + return(afbBitBlt(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, + width, height, dstx, dsty, doBitBlt, pGC->planemask)); +} + +RegionPtr +afbBitBlt(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, + dstx, dsty, doBitBlt, planemask) + register DrawablePtr pSrcDrawable; + register DrawablePtr pDstDrawable; + register GC *pGC; + int srcx, srcy; + int width, height; + int dstx, dsty; + void (*doBitBlt)(); + unsigned long planemask; +{ + RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ + Bool freeSrcClip = FALSE; + + RegionPtr prgnExposed; + RegionRec rgnDst; + DDXPointPtr pptSrc; + register DDXPointPtr ppt; + register BoxPtr pbox; + int i; + register int dx; + register int dy; + xRectangle origSource; + DDXPointRec origDest; + int numRects; + BoxRec fastBox; + int fastClip = 0; /* for fast clipping with pixmap source */ + int fastExpose = 0; /* for fast exposures with pixmap source */ + + origSource.x = srcx; + origSource.y = srcy; + origSource.width = width; + origSource.height = height; + origDest.x = dstx; + origDest.y = dsty; + + if ((pSrcDrawable != pDstDrawable) && pSrcDrawable->pScreen->SourceValidate) + (*pSrcDrawable->pScreen->SourceValidate)(pSrcDrawable, srcx, srcy, width, + height); + + srcx += pSrcDrawable->x; + srcy += pSrcDrawable->y; + + /* clip the source */ + + if (pSrcDrawable->type == DRAWABLE_PIXMAP) + if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) + prgnSrcClip = pGC->pCompositeClip; + else + fastClip = 1; + else if (pGC->subWindowMode == IncludeInferiors) + if (!((WindowPtr)pSrcDrawable)->parent) + /* + * special case bitblt from root window in + * IncludeInferiors mode; just like from a pixmap + */ + fastClip = 1; + else if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) + prgnSrcClip = pGC->pCompositeClip; + else { + prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); + freeSrcClip = TRUE; + } + else + prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; + + fastBox.x1 = srcx; + fastBox.y1 = srcy; + fastBox.x2 = srcx + width; + fastBox.y2 = srcy + height; + + /* Don't create a source region if we are doing a fast clip */ + if (fastClip) { + fastExpose = 1; + /* + * clip the source; if regions extend beyond the source size, + * make sure exposure events get sent + */ + if (fastBox.x1 < pSrcDrawable->x) { + fastBox.x1 = pSrcDrawable->x; + fastExpose = 0; + } + if (fastBox.y1 < pSrcDrawable->y) { + fastBox.y1 = pSrcDrawable->y; + fastExpose = 0; + } + if (fastBox.x2 > pSrcDrawable->x + (int)pSrcDrawable->width) { + fastBox.x2 = pSrcDrawable->x + (int)pSrcDrawable->width; + fastExpose = 0; + } + if (fastBox.y2 > pSrcDrawable->y + (int)pSrcDrawable->height) { + fastBox.y2 = pSrcDrawable->y + (int)pSrcDrawable->height; + fastExpose = 0; + } + } else { + REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1); + REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip); + } + + dstx += pDstDrawable->x; + dsty += pDstDrawable->y; + + if (pDstDrawable->type == DRAWABLE_WINDOW) + if (!((WindowPtr)pDstDrawable)->realized) { + if (!fastClip) + REGION_UNINIT(pGC->pScreen, &rgnDst); + if (freeSrcClip) + REGION_DESTROY(pGC->pScreen, prgnSrcClip); + return NULL; + } + + dx = srcx - dstx; + dy = srcy - dsty; + + /* Translate and clip the dst to the destination composite clip */ + if (fastClip) { + RegionPtr cclip; + + /* Translate the region directly */ + fastBox.x1 -= dx; + fastBox.x2 -= dx; + fastBox.y1 -= dy; + fastBox.y2 -= dy; + + /* If the destination composite clip is one rectangle we can + do the clip directly. Otherwise we have to create a full + blown region and call intersect */ + cclip = pGC->pCompositeClip; + if (REGION_NUM_RECTS(cclip) == 1) { + BoxPtr pBox = REGION_RECTS(cclip); + + if (fastBox.x1 < pBox->x1) + fastBox.x1 = pBox->x1; + if (fastBox.x2 > pBox->x2) + fastBox.x2 = pBox->x2; + if (fastBox.y1 < pBox->y1) + fastBox.y1 = pBox->y1; + if (fastBox.y2 > pBox->y2) + fastBox.y2 = pBox->y2; + + /* Check to see if the region is empty */ + if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) { + REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0); + } else { + REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1); + } + } else { + /* We must turn off fastClip now, since we must create + a full blown region. It is intersected with the + composite clip below. */ + fastClip = 0; + REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1); + } + } else + REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy); + + if (!fastClip) { + REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, + pGC->pCompositeClip); + } + + /* Do bit blitting */ + numRects = REGION_NUM_RECTS(&rgnDst); + if (numRects && width && height) { + if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects * + sizeof(DDXPointRec)))) { + REGION_UNINIT(pGC->pScreen, &rgnDst); + if (freeSrcClip) + REGION_DESTROY(pGC->pScreen, prgnSrcClip); + return NULL; + } + pbox = REGION_RECTS(&rgnDst); + ppt = pptSrc; + for (i = numRects; --i >= 0; pbox++, ppt++) { + ppt->x = pbox->x1 + dx; + ppt->y = pbox->y1 + dy; + } + + (*doBitBlt)(pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, + planemask); + + DEALLOCATE_LOCAL(pptSrc); + } + + prgnExposed = NULL; + if (pGC->fExpose) { + /* Pixmap sources generate a NoExposed (we return NULL to do this) */ + if (!fastExpose) + prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, + origSource.x, origSource.y, + (int)origSource.width, + (int)origSource.height, origDest.x, + origDest.y, (unsigned long)0); + } + REGION_UNINIT(pGC->pScreen, &rgnDst); + if (freeSrcClip) + REGION_DESTROY(pGC->pScreen, prgnSrcClip); + return prgnExposed; +} + +RegionPtr +afbCopyPlane(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, + dstx, dsty, plane) +DrawablePtr pSrcDrawable, pDstDrawable; +register GC *pGC; +int srcx, srcy; +int width, height; +int dstx, dsty; +unsigned long plane; +{ + int alu; + RegionPtr prgnExposed = NULL; + unsigned long old_planemask; + + if (pDstDrawable->depth == 1) { + old_planemask = pGC->planemask; + pGC->planemask = plane; + if ((pGC->fgPixel & 1) == 1 && (pGC->bgPixel & 1) == 0) { + prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty); + } else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1)) { + unsigned char rop; + + afbReduceRop(pGC->alu, pGC->fgPixel, 1, 1, &rop); + alu = pGC->alu; + pGC->alu = rop; + prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, dstx, + dsty); + pGC->alu = alu; + } else { /* need to invert the src */ + alu = pGC->alu; + pGC->alu = afbInverseAlu[alu]; + prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, dstx, + dsty); + pGC->alu = alu; + } + pGC->planemask = old_planemask; + } else { + int free_pixmap = FALSE; + PixmapPtr pBitmap = (PixmapPtr)pSrcDrawable; + ScreenPtr pScreen = pSrcDrawable->pScreen; + GCPtr pGC1 = NULL; + + if (pSrcDrawable == pDstDrawable || + pSrcDrawable->type == DRAWABLE_WINDOW || pSrcDrawable->depth != 1) { + /* Copy a plane from source drawable to a tmp 1-bit deep pixmap */ + /* XXX: Range check width and height */ + pBitmap = (*pScreen->CreatePixmap)(pScreen, width, height, 1); + + if (!pBitmap) + return(NULL); + pGC1 = GetScratchGC(1, pScreen); + if (!pGC1) { + (*pScreen->DestroyPixmap)(pBitmap); + return(NULL); + } + ValidateGC((DrawablePtr)pBitmap, pGC1); + (void)afbBitBlt(pSrcDrawable, (DrawablePtr)pBitmap, pGC1, srcx, srcy, + width, height, 0, 0, afbDoBitbltCopy, plane); + free_pixmap = TRUE; + } +#if 0 + else { + /* XXX: could cope with N-deep pixmap source case without using tmp + * src bitmap by setting up a scratch pixmap header and fiddle + * around with the pbits pointer. + */ + } +#endif + afbReduceOpaqueStipple(pGC->fgPixel, pGC->bgPixel, pGC->planemask, + pGC->depth, afbRropsOS); + (void)afbBitBlt((DrawablePtr)pBitmap, pDstDrawable, pGC, 0, 0, width, + height, dstx, dsty, afbCopy1ToN, pGC->planemask); + if (free_pixmap) { + (*pScreen->DestroyPixmap)(pBitmap); + FreeScratchGC(pGC1); + } + + if (pGC->fExpose) + prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, srcx, + srcy, width, height, dstx, dsty, + plane); + } + return prgnExposed; +} + +void +afbCopy1ToN(pSrc, pDst, alu, prgnDst, pptSrc, planemask) + DrawablePtr pSrc, pDst; + int alu; + RegionPtr prgnDst; + DDXPointPtr pptSrc; + unsigned long planemask; +{ + int numRects = REGION_NUM_RECTS(prgnDst); + BoxPtr pbox = REGION_RECTS(prgnDst); + int r; + + for (r = 0; r < numRects; r++, pbox++, pptSrc++) { + int dx = pptSrc->x; + int dy = pptSrc->y; + + if (alu == GXcopy) + afbOpaqueStippleAreaCopy(pDst, 1, pbox, alu, (PixmapPtr)pSrc, dx, dy, + afbRropsOS, planemask); + else + afbOpaqueStippleAreaGeneral(pDst, 1, pbox, alu, (PixmapPtr)pSrc, dx, + dy, afbRropsOS, planemask); + } +} diff --git a/afb/afbblt.c b/afb/afbblt.c new file mode 100644 index 000000000..c0b48130e --- /dev/null +++ b/afb/afbblt.c @@ -0,0 +1,559 @@ +/* $XFree86: xc/programs/Xserver/afb/afbblt.c,v 3.1 2001/10/28 03:32:57 tsi Exp $ */ +/* + * afb copy area + */ + +/* + +Copyright (c) 1989 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +Author: Keith Packard + +*/ +/* $XConsortium: afbblt.c,v 1.11 94/04/17 20:28:16 dpw Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "afb.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "maskbits.h" +#include "fastblt.h" +#include "mergerop.h" + +void +MROP_NAME(afbDoBitblt)(pSrc, pDst, alu, prgnDst, pptSrc, planemask) + DrawablePtr pSrc, pDst; + int alu; + RegionPtr prgnDst; + DDXPointPtr pptSrc; + unsigned long planemask; +{ + PixelType *psrcBase, *pdstBase; /* start of src and dst bitmaps */ + int widthSrc, widthDst; /* add to get to same position in next line */ + int sizeSrc, sizeDst; + + BoxPtr pbox; + int nbox; + + BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2; + /* temporaries for shuffling rectangles */ + DDXPointPtr pptTmp, pptNew1, pptNew2; + /* shuffling boxes entails shuffling the + source points too */ + int w, h; + int xdir; /* 1 = left right, -1 = right left/ */ + int ydir; /* 1 = top down, -1 = bottom up */ + + PixelType *psrcLine, *pdstLine; + /* pointers to line with current src and dst */ + register PixelType *psrc; /* pointer to current src longword */ + register PixelType *pdst; /* pointer to current dst longword */ + + MROP_DECLARE_REG() + + /* following used for looping through a line */ + PixelType startmask, endmask; /* masks for writing ends of dst */ + int nlMiddle; /* whole longwords in dst */ + int xoffSrc, xoffDst; + register int leftShift, rightShift; + register PixelType bits; + register PixelType bits1; + register int nl; /* temp copy of nlMiddle */ + + int careful; + int depthSrc; + int depthDst; + + MROP_INITIALIZE(alu,0); + + afbGetPixelWidthSizeDepthAndPointer(pSrc, widthSrc, sizeSrc, depthSrc, + psrcBase); + afbGetPixelWidthSizeDepthAndPointer(pDst, widthDst, sizeDst, depthDst, + pdstBase); + + /* Special case where depth of dest pixmap is 1 but source pixmap isn't + * Used for GetImage to copy a plane from a source pixmap to a particular + * dest pixmap plane. + * Note: planemask should have only one bit set or several planes from + * the source will be copied to the same dest plane. + */ + if (depthDst == 1 && depthDst != depthSrc) + sizeDst = 0; + + /* XXX we have to err on the side of safety when both are windows, + * because we don't know if IncludeInferiors is being used. + */ + careful = ((pSrc == pDst) || + ((pSrc->type == DRAWABLE_WINDOW) && + (pDst->type == DRAWABLE_WINDOW))); + + pbox = REGION_RECTS(prgnDst); + nbox = REGION_NUM_RECTS(prgnDst); + + pboxNew1 = NULL; + pptNew1 = NULL; + pboxNew2 = NULL; + pptNew2 = NULL; + if (careful && (pptSrc->y < pbox->y1)) { + /* walk source botttom to top */ + ydir = -1; + widthSrc = -widthSrc; + widthDst = -widthDst; + + if (nbox > 1) { + /* keep ordering in each band, reverse order of bands */ + pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); + if(!pboxNew1) + return; + pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); + if(!pptNew1) { + DEALLOCATE_LOCAL(pboxNew1); + return; + } + pboxBase = pboxNext = pbox+nbox-1; + while (pboxBase >= pbox) { + while ((pboxNext >= pbox) && + (pboxBase->y1 == pboxNext->y1)) + pboxNext--; + pboxTmp = pboxNext+1; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp <= pboxBase) { + *pboxNew1++ = *pboxTmp++; + *pptNew1++ = *pptTmp++; + } + pboxBase = pboxNext; + } + pboxNew1 -= nbox; + pbox = pboxNew1; + pptNew1 -= nbox; + pptSrc = pptNew1; + } + } else { + /* walk source top to bottom */ + ydir = 1; + } + + if (careful && (pptSrc->x < pbox->x1)) { + /* walk source right to left */ + xdir = -1; + + if (nbox > 1) { + /* reverse order of rects in each band */ + pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); + pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); + if(!pboxNew2 || !pptNew2) { + if (pptNew2) + DEALLOCATE_LOCAL(pptNew2); + if (pboxNew2) + DEALLOCATE_LOCAL(pboxNew2); + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } + return; + } + pboxBase = pboxNext = pbox; + while (pboxBase < pbox+nbox) { + while ((pboxNext < pbox+nbox) && (pboxNext->y1 == pboxBase->y1)) + pboxNext++; + pboxTmp = pboxNext; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp != pboxBase) { + *pboxNew2++ = *--pboxTmp; + *pptNew2++ = *--pptTmp; + } + pboxBase = pboxNext; + } + pboxNew2 -= nbox; + pbox = pboxNew2; + pptNew2 -= nbox; + pptSrc = pptNew2; + } + } else { + /* walk source left to right */ + xdir = 1; + } + + while(nbox--) { + int d; + for (d = 0; d < depthSrc; d++) { + PixelType *psrcB; + PixelType *pdstB; + + if (!(planemask & (1 << d))) + continue; + + psrcB = psrcBase + sizeSrc * d; /* @@@ NEXT PLANE @@@ */ + pdstB = pdstBase + sizeDst * d; /* @@@ NEXT PLANE @@@ */ + + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + if (ydir == -1) { /* start at last scanline of rectangle */ + psrcLine = afbScanlineDeltaSrc(psrcB, -(pptSrc->y+h-1), widthSrc); + pdstLine = afbScanlineDeltaDst(pdstB, -(pbox->y2-1), widthDst); + } else { /* start at first scanline */ + psrcLine = afbScanlineDeltaSrc(psrcB, pptSrc->y, widthSrc); + pdstLine = afbScanlineDeltaDst(pdstB, pbox->y1, widthDst); + } + if ((pbox->x1 & PIM) + w <= PPW) { + maskpartialbits (pbox->x1, w, startmask); + endmask = 0; + nlMiddle = 0; + } else { + maskbits(pbox->x1, w, startmask, endmask, nlMiddle); + } + if (xdir == 1) { + xoffSrc = pptSrc->x & PIM; + xoffDst = pbox->x1 & PIM; + pdstLine += (pbox->x1 >> PWSH); + psrcLine += (pptSrc->x >> PWSH); +#ifdef DO_UNALIGNED_BITBLT + nl = xoffSrc - xoffDst; + psrcLine = (PixelType *)(((unsigned char *) psrcLine) + nl); +#else + if (xoffSrc == xoffDst) +#endif + { + while (h--) { + psrc = psrcLine; + pdst = pdstLine; + if (startmask) { + *pdst = MROP_MASK(*psrc, *pdst, startmask); + psrc++; + pdst++; + } + nl = nlMiddle; + +#ifdef LARGE_INSTRUCTION_CACHE +#ifdef FAST_CONSTANT_OFFSET_MODE + + psrc += nl & (UNROLL-1); + pdst += nl & (UNROLL-1); + +#define BodyOdd(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]); +#define BodyEven(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]); + +#define LoopReset \ +pdst += UNROLL; \ +psrc += UNROLL; + +#else + +#define BodyOdd(n) *pdst = MROP_SOLID (*psrc, *pdst); pdst++; psrc++; +#define BodyEven(n) BodyOdd(n) + +#define LoopReset ; + +#endif + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else +#ifdef NOTDEF + /* you'd think this would be faster -- + * a single instruction instead of 6 + * but measurements show it to be ~15% slower + */ + while ((nl -= 6) >= 0) { + asm ("moveml %1+,#0x0c0f;moveml#0x0c0f,%0" + : "=m" (*(char *)pdst) + : "m" (*(char *)psrc) + : "d0", "d1", "d2", "d3", + "a2", "a3"); + pdst += 6; + } + nl += 6; + while (nl--) + *pdst++ = *psrc++; +#endif + DuffL(nl, label1, + *pdst = MROP_SOLID (*psrc, *pdst); + pdst++; psrc++;) +#endif + + if (endmask) + *pdst = MROP_MASK(*psrc, *pdst, endmask); + afbScanlineIncDst(pdstLine, widthDst); + afbScanlineIncSrc(psrcLine, widthSrc); + } + } +#ifndef DO_UNALIGNED_BITBLT + else { + if (xoffSrc > xoffDst) { + leftShift = (xoffSrc - xoffDst); + rightShift = PPW - leftShift; + } else { + rightShift = (xoffDst - xoffSrc); + leftShift = PPW - rightShift; + } + while (h--) { + psrc = psrcLine; + pdst = pdstLine; + bits = 0; + if (xoffSrc > xoffDst) + bits = *psrc++; + if (startmask) { + bits1 = BitLeft(bits,leftShift); + bits = *psrc++; + bits1 |= BitRight(bits,rightShift); + *pdst = MROP_MASK(bits1, *pdst, startmask); + pdst++; + } + nl = nlMiddle; + +#ifdef LARGE_INSTRUCTION_CACHE + bits1 = bits; + +#ifdef FAST_CONSTANT_OFFSET_MODE + + psrc += nl & (UNROLL-1); + pdst += nl & (UNROLL-1); + +#define BodyOdd(n) \ +bits = psrc[-n]; \ +pdst[-n] = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), pdst[-n]); + +#define BodyEven(n) \ +bits1 = psrc[-n]; \ +pdst[-n] = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), pdst[-n]); + +#define LoopReset \ +pdst += UNROLL; \ +psrc += UNROLL; + +#else + +#define BodyOdd(n) \ +bits = *psrc++; \ +*pdst = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), *pdst); \ +pdst++; + +#define BodyEven(n) \ +bits1 = *psrc++; \ +*pdst = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), *pdst); \ +pdst++; + +#define LoopReset ; + +#endif /* !FAST_CONSTANT_OFFSET_MODE */ + + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL(nl,label2, + bits1 = BitLeft(bits, leftShift); + bits = *psrc++; + *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst); + pdst++; + ) +#endif + + if (endmask) { + bits1 = BitLeft(bits, leftShift); + if (BitLeft(endmask, rightShift)) { + bits = *psrc; + bits1 |= BitRight(bits, rightShift); + } + *pdst = MROP_MASK (bits1, *pdst, endmask); + } + afbScanlineIncDst(pdstLine, widthDst); + afbScanlineIncSrc(psrcLine, widthSrc); + } + } +#endif /* DO_UNALIGNED_BITBLT */ + } else { /* xdir == -1 */ + xoffSrc = (pptSrc->x + w - 1) & PIM; + xoffDst = (pbox->x2 - 1) & PIM; + pdstLine += ((pbox->x2-1) >> PWSH) + 1; + psrcLine += ((pptSrc->x+w - 1) >> PWSH) + 1; +#ifdef DO_UNALIGNED_BITBLT + nl = xoffSrc - xoffDst; + psrcLine = (PixelType *) + (((unsigned char *) psrcLine) + nl); +#else + if (xoffSrc == xoffDst) +#endif + { + while (h--) { + psrc = psrcLine; + pdst = pdstLine; + if (endmask) { + pdst--; + psrc--; + *pdst = MROP_MASK (*psrc, *pdst, endmask); + } + nl = nlMiddle; + +#ifdef LARGE_INSTRUCTION_CACHE +#ifdef FAST_CONSTANT_OFFSET_MODE + psrc -= nl & (UNROLL - 1); + pdst -= nl & (UNROLL - 1); + +#define BodyOdd(n) pdst[n-1] = MROP_SOLID (psrc[n-1], pdst[n-1]); + +#define BodyEven(n) BodyOdd(n) + +#define LoopReset \ +pdst -= UNROLL;\ +psrc -= UNROLL; + +#else + +#define BodyOdd(n) --pdst; --psrc; *pdst = MROP_SOLID(*psrc, *pdst); +#define BodyEven(n) BodyOdd(n) +#define LoopReset ; + +#endif + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL(nl,label3, + --pdst; --psrc; *pdst = MROP_SOLID (*psrc, *pdst);) +#endif + + if (startmask) { + --pdst; + --psrc; + *pdst = MROP_MASK(*psrc, *pdst, startmask); + } + afbScanlineIncDst(pdstLine, widthDst); + afbScanlineIncSrc(psrcLine, widthSrc); + } + } +#ifndef DO_UNALIGNED_BITBLT + else { + if (xoffDst > xoffSrc) { + rightShift = (xoffDst - xoffSrc); + leftShift = PPW - rightShift; + } else { + leftShift = (xoffSrc - xoffDst); + rightShift = PPW - leftShift; + } + while (h--) { + psrc = psrcLine; + pdst = pdstLine; + bits = 0; + if (xoffDst > xoffSrc) + bits = *--psrc; + if (endmask) { + bits1 = BitRight(bits, rightShift); + bits = *--psrc; + bits1 |= BitLeft(bits, leftShift); + pdst--; + *pdst = MROP_MASK(bits1, *pdst, endmask); + } + nl = nlMiddle; + +#ifdef LARGE_INSTRUCTION_CACHE + bits1 = bits; +#ifdef FAST_CONSTANT_OFFSET_MODE + psrc -= nl & (UNROLL - 1); + pdst -= nl & (UNROLL - 1); + +#define BodyOdd(n) \ +bits = psrc[n-1]; \ +pdst[n-1] = MROP_SOLID(BitRight(bits1, rightShift) | BitLeft(bits, leftShift),pdst[n-1]); + +#define BodyEven(n) \ +bits1 = psrc[n-1]; \ +pdst[n-1] = MROP_SOLID(BitRight(bits, rightShift) | BitLeft(bits1, leftShift),pdst[n-1]); + +#define LoopReset \ +pdst -= UNROLL; \ +psrc -= UNROLL; + +#else + +#define BodyOdd(n) \ +bits = *--psrc; --pdst; \ +*pdst = MROP_SOLID(BitRight(bits1, rightShift) | BitLeft(bits, leftShift),*pdst); + +#define BodyEven(n) \ +bits1 = *--psrc; --pdst; \ +*pdst = MROP_SOLID(BitRight(bits, rightShift) | BitLeft(bits1, leftShift),*pdst); + +#define LoopReset ; + +#endif + + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL(nl, label4, + bits1 = BitRight(bits, rightShift); + bits = *--psrc; + --pdst; + *pdst = MROP_SOLID(bits1 | BitLeft(bits, leftShift),*pdst); + ) +#endif + + if (startmask) { + bits1 = BitRight(bits, rightShift); + if (BitRight (startmask, leftShift)) { + bits = *--psrc; + bits1 |= BitLeft(bits, leftShift); + } + --pdst; + *pdst = MROP_MASK(bits1, *pdst, startmask); + } + afbScanlineIncDst(pdstLine, widthDst); + afbScanlineIncSrc(psrcLine, widthSrc); + } + } +#endif + } + } + pbox++; + pptSrc++; + } + if (pboxNew2) { + DEALLOCATE_LOCAL(pptNew2); + DEALLOCATE_LOCAL(pboxNew2); + } + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } +} diff --git a/afb/afbbres.c b/afb/afbbres.c new file mode 100644 index 000000000..227f3bc1f --- /dev/null +++ b/afb/afbbres.c @@ -0,0 +1,321 @@ +/* $XFree86: xc/programs/Xserver/afb/afbbres.c,v 3.0 1996/08/18 01:45:25 dawes Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbbres.c,v 1.22 94/04/17 20:28:17 dpw Exp $ */ + +#include "X.h" +#include "misc.h" +#include "afb.h" +#include "maskbits.h" +#include "miline.h" + +/* Solid bresenham line */ +/* NOTES + e2 is used less often than e1, so it's not in a register +*/ + +void +afbBresS(addrlbase, nlwidth, sizeDst, depthDst, signdx, signdy, axis, x1, y1, + e, e1, e2, len, rrops) +PixelType *addrlbase; /* pointer to base of bitmap */ +int nlwidth; /* width in longwords of bitmap */ +int sizeDst; +int depthDst; +int signdx, signdy; /* signs of directions */ +int axis; /* major axis (Y_AXIS or X_AXIS) */ +int x1, y1; /* initial point */ +register int e; /* error accumulator */ +register int e1; /* bresenham increments */ +int e2; +int len; /* length of line */ +unsigned char *rrops; +{ + register int yinc; /* increment to next scanline, in bytes */ + register PixelType *addrl; /* bitmask long pointer */ + register PixelType bit; /* current bit being set/cleared/etc. */ + PixelType leftbit = mask[0]; /* leftmost bit to process in new word */ + PixelType rightbit = mask[PPW-1]; /* rightmost bit to process in new word */ + + register int e3 = e2-e1; + PixelType tmp; + int saveE; + int saveLen; + int d; + + /* point to longword containing first point */ + yinc = signdy * nlwidth; + e = e-e1; /* to make looping easier */ + + if (!len) + return; + + saveLen = len; + saveE = e; + + for (d = 0; d < depthDst; d++) { + addrl = afbScanline(addrlbase, x1, y1, nlwidth); + addrlbase += sizeDst; /* @@@ NEXT PLANE @@@ */ + len = saveLen; + e = saveE; + bit = mask[x1 & PIM]; + + switch (rrops[d]) { + case RROP_BLACK: + if (axis == X_AXIS) { + if (signdx > 0) { + tmp = *addrl; + for (;;) { + tmp &= ~bit; + if (!--len) + break; + bit = SCRRIGHT(bit,1); + e += e1; + if (e >= 0) { + *addrl = tmp; + afbScanlineInc(addrl, yinc); + e += e3; + if (!bit) { + bit = leftbit; + addrl ++; + } + tmp = *addrl; + } else if (!bit) { + *addrl = tmp; + bit = leftbit; + addrl ++; + tmp = *addrl; + } + } + *addrl = tmp; + } else { + tmp = *addrl; + for (;;) { + tmp &= ~bit; + if (!--len) + break; + e += e1; + bit = SCRLEFT(bit,1); + if (e >= 0) { + *addrl = tmp; + afbScanlineInc(addrl, yinc); + e += e3; + if (!bit) { + bit = rightbit; + addrl --; + } + tmp = *addrl; + } else if (!bit) { + *addrl = tmp; + bit = rightbit; + addrl --; + tmp = *addrl; + } + } + *addrl = tmp; + } + } /* if X_AXIS */ else { + if (signdx > 0) { + while(len--) { + *addrl &= ~bit; + e += e1; + if (e >= 0) { + bit = SCRRIGHT(bit,1); + if (!bit) { bit = leftbit;addrl ++; } + e += e3; + } + afbScanlineInc(addrl, yinc); + } + } else { + while(len--) { + *addrl &= ~bit; + e += e1; + if (e >= 0) { + bit = SCRLEFT(bit,1); + if (!bit) { bit = rightbit;addrl --; } + e += e3; + } + afbScanlineInc(addrl, yinc); + } + } + } /* else Y_AXIS */ + break; + + case RROP_WHITE: + if (axis == X_AXIS) { + if (signdx > 0) { + tmp = *addrl; + for (;;) { + tmp |= bit; + if (!--len) + break; + e += e1; + bit = SCRRIGHT(bit,1); + if (e >= 0) { + *addrl = tmp; + afbScanlineInc(addrl, yinc); + e += e3; + if (!bit) { + bit = leftbit; + addrl ++; + } + tmp = *addrl; + } else if (!bit) { + *addrl = tmp; + bit = leftbit; + addrl ++; + tmp = *addrl; + } + } + *addrl = tmp; + } else { + tmp = *addrl; + for (;;) { + tmp |= bit; + if (!--len) + break; + e += e1; + bit = SCRLEFT(bit,1); + if (e >= 0) { + *addrl = tmp; + afbScanlineInc(addrl, yinc); + e += e3; + if (!bit) { + bit = rightbit; + addrl --; + } + tmp = *addrl; + } else if (!bit) { + *addrl = tmp; + bit = rightbit; + addrl --; + tmp = *addrl; + } + } + *addrl = tmp; + } + } /* if X_AXIS */ else { + if (signdx > 0) { + while(len--) { + *addrl |= bit; + e += e1; + if (e >= 0) { + bit = SCRRIGHT(bit,1); + if (!bit) { bit = leftbit;addrl ++; } + e += e3; + } + afbScanlineInc(addrl, yinc); + } + } else { + while(len--) { + *addrl |= bit; + e += e1; + if (e >= 0) { + bit = SCRLEFT(bit,1); + if (!bit) { bit = rightbit;addrl --; } + e += e3; + } + afbScanlineInc(addrl, yinc); + } + } + } /* else Y_AXIS */ + break; + + case RROP_INVERT: + if (axis == X_AXIS) { + if (signdx > 0) { + while(len--) { + *addrl ^= bit; + e += e1; + if (e >= 0) { + afbScanlineInc(addrl, yinc); + e += e3; + } + bit = SCRRIGHT(bit,1); + if (!bit) { bit = leftbit;addrl ++; } + } + } else { + while(len--) { + *addrl ^= bit; + e += e1; + if (e >= 0) { + afbScanlineInc(addrl, yinc); + e += e3; + } + bit = SCRLEFT(bit,1); + if (!bit) { bit = rightbit;addrl --; } + } + } + } /* if X_AXIS */ else { + if (signdx > 0) { + while(len--) { + *addrl ^= bit; + e += e1; + if (e >= 0) { + bit = SCRRIGHT(bit,1); + if (!bit) { bit = leftbit;addrl ++; } + e += e3; + } + afbScanlineInc(addrl, yinc); + } + } else { + while(len--) { + *addrl ^= bit; + e += e1; + if (e >= 0) { + bit = SCRLEFT(bit,1); + if (!bit) { bit = rightbit; addrl --; } + e += e3; + } + afbScanlineInc(addrl, yinc); + } + } + } /* else Y_AXIS */ + } /* switch */ + } /* for (d = ... ) */ +} diff --git a/afb/afbbresd.c b/afb/afbbresd.c new file mode 100644 index 000000000..57309175e --- /dev/null +++ b/afb/afbbresd.c @@ -0,0 +1,212 @@ +/* $XFree86: xc/programs/Xserver/afb/afbbresd.c,v 3.0 1996/08/18 01:45:26 dawes Exp $ */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbbresd.c,v 1.10 94/04/17 20:28:18 dpw Exp $ */ + +#include "X.h" +#include "misc.h" +#include "afb.h" +#include "maskbits.h" +#include "miline.h" + +/* Dashed bresenham line */ + +#define StepDash\ + if (!--dashRemaining) { \ + if (++ dashIndex == numInDashList) \ + dashIndex = 0; \ + dashRemaining = pDash[dashIndex]; \ + rop = fgrop; \ + if (dashIndex & 1) \ + rop = bgrop; \ + } + +void +afbBresD(pdashIndex, pDash, numInDashList, pdashOffset, isDoubleDash, + addrlbase, nlwidth, sizeDst, depthDst, + signdx, signdy, axis, x1, y1, e, e1, e2, len, rrops, bgrrops) +int *pdashIndex; /* current dash */ +unsigned char *pDash; /* dash list */ +int numInDashList; /* total length of dash list */ +int *pdashOffset; /* offset into current dash */ +int isDoubleDash; +PixelType *addrlbase; /* pointer to base of bitmap */ +int nlwidth; /* width in longwords of bitmap */ +int sizeDst; +int depthDst; +int signdx, signdy; /* signs of directions */ +int axis; /* major axis (Y_AXIS or X_AXIS) */ +int x1, y1; /* initial point */ +register int e; /* error accumulator */ +register int e1; /* bresenham increments */ +int e2; +int len; /* length of line */ +unsigned char *rrops; +unsigned char *bgrrops; +{ + register int yinc; /* increment to next scanline, in bytes */ + register PixelType *addrl; + register int e3 = e2-e1; + register unsigned long bit; + PixelType leftbit = mask[0]; /* leftmost bit to process in new word */ + PixelType rightbit = mask[PPW-1]; /* rightmost bit to process in new word */ + int dashIndex; + int dashOffset; + int dashRemaining; + int rop; + int fgrop; + int bgrop; + int saveE; + int saveLen; + int d; + + dashOffset = *pdashOffset; + dashIndex = *pdashIndex; + dashRemaining = pDash[dashIndex] - dashOffset; + /* point to longword containing first point */ + + yinc = signdy * nlwidth; + e = e-e1; /* to make looping easier */ + + saveE = e; + saveLen = len; + + for (d = 0; d < depthDst; d++) { + addrl = afbScanline(addrlbase, x1, y1, nlwidth); + addrlbase += sizeDst; /* @@@ NEXT PLANE @@@ */ + + fgrop = rrops[d]; + bgrop = bgrrops[d]; + + e = saveE; + len = saveLen; + bit = mask[x1 & PIM]; + + rop = fgrop; + if (!isDoubleDash) + bgrop = -1; + if (dashIndex & 1) + rop = bgrop; + + if (axis == X_AXIS) { + if (signdx > 0) { + while(len--) { + if (rop == RROP_BLACK) + *addrl &= ~bit; + else if (rop == RROP_WHITE) + *addrl |= bit; + else if (rop == RROP_INVERT) + *addrl ^= bit; + e += e1; + if (e >= 0) { + afbScanlineInc(addrl, yinc); + e += e3; + } + bit = SCRRIGHT(bit,1); + if (!bit) { bit = leftbit;addrl ++; } + StepDash + } + } else { + while(len--) { + if (rop == RROP_BLACK) + *addrl &= ~bit; + else if (rop == RROP_WHITE) + *addrl |= bit; + else if (rop == RROP_INVERT) + *addrl ^= bit; + e += e1; + if (e >= 0) { + afbScanlineInc(addrl, yinc); + e += e3; + } + bit = SCRLEFT(bit,1); + if (!bit) { bit = rightbit;addrl --; } + StepDash + } + } + } /* if X_AXIS */ else { + if (signdx > 0) { + while(len--) { + if (rop == RROP_BLACK) + *addrl &= ~bit; + else if (rop == RROP_WHITE) + *addrl |= bit; + else if (rop == RROP_INVERT) + *addrl ^= bit; + e += e1; + if (e >= 0) { + bit = SCRRIGHT(bit,1); + if (!bit) { bit = leftbit;addrl ++; } + e += e3; + } + afbScanlineInc(addrl, yinc); + StepDash + } + } else { + while(len--) { + if (rop == RROP_BLACK) + *addrl &= ~bit; + else if (rop == RROP_WHITE) + *addrl |= bit; + else if (rop == RROP_INVERT) + *addrl ^= bit; + e += e1; + if (e >= 0) { + bit = SCRLEFT(bit,1); + if (!bit) { bit = rightbit;addrl --; } + e += e3; + } + afbScanlineInc(addrl, yinc); + StepDash + } + } + } /* else Y_AXIS */ + } /* for (d = ...) */ + *pdashIndex = dashIndex; + *pdashOffset = pDash[dashIndex] - dashRemaining; +} diff --git a/afb/afbbstore.c b/afb/afbbstore.c new file mode 100644 index 000000000..725f93d48 --- /dev/null +++ b/afb/afbbstore.c @@ -0,0 +1,152 @@ +/* $XFree86: xc/programs/Xserver/afb/afbbstore.c,v 3.0 1996/08/18 01:45:28 dawes Exp $ */ +/* $XConsortium: afbbstore.c,v 5.7 94/04/17 20:28:18 dpw Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/* + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + +#include "afb.h" +#include "X.h" +#include "mibstore.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "windowstr.h" + +/*- + *----------------------------------------------------------------------- + * afbSaveAreas -- + * Function called by miSaveAreas to actually fetch the areas to be + * saved into the backing pixmap. This is very simple to do, since + * afbDoBitblt is designed for this very thing. The region to save is + * already destination-relative and we're given the offset to the + * window origin, so we have only to create an array of points of the + * u.l. corners of the boxes in the region translated to the screen + * coordinate system and fetch the screen pixmap out of its devPrivate + * field.... + * + * Results: + * None. + * + * Side Effects: + * Data are copied from the screen into the pixmap. + * + *----------------------------------------------------------------------- + */ +void +afbSaveAreas(pPixmap, prgnSave, xorg, yorg, pWin) + PixmapPtr pPixmap; /* Backing pixmap */ + RegionPtr prgnSave; /* Region to save (pixmap-relative) */ + int xorg; /* X origin of region */ + int yorg; /* Y origin of region */ + WindowPtr pWin; +{ + register DDXPointPtr pPt; + DDXPointPtr pPtsInit; + register BoxPtr pBox; + register int numRects; + + numRects = REGION_NUM_RECTS(prgnSave); + pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(numRects * sizeof(DDXPointRec)); + if (!pPtsInit) + return; + + pBox = REGION_RECTS(prgnSave); + pPt = pPtsInit; + while (numRects--) { + pPt->x = pBox->x1 + xorg; + pPt->y = pBox->y1 + yorg; + pPt++; + pBox++; + } + + afbDoBitblt((DrawablePtr)pPixmap->drawable.pScreen->devPrivates[afbScreenPrivateIndex].ptr, + (DrawablePtr)pPixmap, + GXcopy, + prgnSave, + pPtsInit, wBackingBitPlanes (pWin)); + + DEALLOCATE_LOCAL(pPtsInit); +} + +/*- + *----------------------------------------------------------------------- + * afbRestoreAreas -- + * Function called by miRestoreAreas to actually fetch the areas to be + * restored from the backing pixmap. This is very simple to do, since + * afbDoBitblt is designed for this very thing. The region to restore is + * already destination-relative and we're given the offset to the + * window origin, so we have only to create an array of points of the + * u.l. corners of the boxes in the region translated to the pixmap + * coordinate system and fetch the screen pixmap out of its devPrivate + * field.... + * + * Results: + * None. + * + * Side Effects: + * Data are copied from the pixmap into the screen. + * + *----------------------------------------------------------------------- + */ +void +afbRestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin) + PixmapPtr pPixmap; /* Backing pixmap */ + RegionPtr prgnRestore; /* Region to restore (screen-relative)*/ + int xorg; /* X origin of window */ + int yorg; /* Y origin of window */ + WindowPtr pWin; +{ + register DDXPointPtr pPt; + DDXPointPtr pPtsInit; + register BoxPtr pBox; + register int numRects; + + numRects = REGION_NUM_RECTS(prgnRestore); + pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(numRects*sizeof(DDXPointRec)); + if (!pPtsInit) + return; + + pBox = REGION_RECTS(prgnRestore); + pPt = pPtsInit; + while (numRects--) { + pPt->x = pBox->x1 - xorg; + pPt->y = pBox->y1 - yorg; + pPt++; + pBox++; + } + + afbDoBitblt((DrawablePtr)pPixmap, + (DrawablePtr)pPixmap->drawable.pScreen->devPrivates[afbScreenPrivateIndex].ptr, + GXcopy, + prgnRestore, + pPtsInit, wBackingBitPlanes (pWin)); + + DEALLOCATE_LOCAL(pPtsInit); +} diff --git a/afb/afbclip.c b/afb/afbclip.c new file mode 100644 index 000000000..9e00fbcea --- /dev/null +++ b/afb/afbclip.c @@ -0,0 +1,245 @@ +/* $XFree86: xc/programs/Xserver/afb/afbclip.c,v 3.2 2001/10/28 03:32:57 tsi Exp $ */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbclip.c,v 5.6 94/04/17 20:28:19 dpw Exp $ */ + +#include "X.h" +#include "miscstruct.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "regionstr.h" +#include "gc.h" +#include "maskbits.h" +#include "mi.h" +#include "afb.h" + +#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \ +if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \ + (!((reg)->data->numRects && \ + ((r-1)->y1 == (ry1)) && \ + ((r-1)->y2 == (ry2)) && \ + ((r-1)->x1 <= (rx1)) && \ + ((r-1)->x2 >= (rx2))))) \ +{ \ + if ((reg)->data->numRects == (reg)->data->size) \ + { \ + miRectAlloc(reg, 1); \ + fr = REGION_BOXPTR(reg); \ + r = fr + (reg)->data->numRects; \ + } \ + r->x1 = (rx1); \ + r->y1 = (ry1); \ + r->x2 = (rx2); \ + r->y2 = (ry2); \ + (reg)->data->numRects++; \ + if(r->x1 < (reg)->extents.x1) \ + (reg)->extents.x1 = r->x1; \ + if(r->x2 > (reg)->extents.x2) \ + (reg)->extents.x2 = r->x2; \ + r++; \ +} + +/* Convert bitmap clip mask into clipping region. + * First, goes through each line and makes boxes by noting the transitions + * from 0 to 1 and 1 to 0. + * Then it coalesces the current line with the previous if they have boxes + * at the same X coordinates. + */ +RegionPtr +afbPixmapToRegion(pPix) + PixmapPtr pPix; +{ + register RegionPtr pReg; + register PixelType *pw, w; + register int ib; + int width, h, base, rx1 = 0, crects; + PixelType *pwLineEnd; + int irectPrevStart, irectLineStart; + register BoxPtr prectO, prectN; + BoxPtr FirstRect, rects, prectLineStart; + Bool fInBox, fSame; + register PixelType mask0 = mask[0]; + PixelType *pwLine; + int nWidth; + + pReg = REGION_CREATE(pPix->drawable.pScreen, NULL, 1); + if(!pReg) + return NullRegion; + FirstRect = REGION_BOXPTR(pReg); + rects = FirstRect; + + pwLine = (PixelType *) pPix->devPrivate.ptr; + nWidth = pPix->devKind / PGSZB; + + width = pPix->drawable.width; + pReg->extents.x1 = width - 1; + pReg->extents.x2 = 0; + irectPrevStart = -1; + for(h = 0; h < pPix->drawable.height; h++) { + pw = pwLine; + pwLine += nWidth; + irectLineStart = rects - FirstRect; + /* If the Screen left most bit of the word is set, we're starting in + * a box */ + if(*pw & mask0) { + fInBox = TRUE; + rx1 = 0; + } + else + fInBox = FALSE; + /* Process all words which are fully in the pixmap */ + pwLineEnd = pw + (width >> PWSH); + for (base = 0; pw < pwLineEnd; base += PPW) { + w = *pw++; + if (fInBox) { + if (!~w) + continue; + } else { + if (!w) + continue; + } + for(ib = 0; ib < PPW; ib++) { + /* If the Screen left most bit of the word is set, we're + * starting a box */ + if(w & mask0) { + if(!fInBox) { + rx1 = base + ib; + /* start new box */ + fInBox = TRUE; + } + } else { + if(fInBox) { + /* end box */ + ADDRECT(pReg, rects, FirstRect, + rx1, h, base + ib, h + 1); + fInBox = FALSE; + } + } + /* Shift the word VISUALLY left one. */ + w = SCRLEFT(w, 1); + } + } + if(width & PIM) { + /* Process final partial word on line */ + w = *pw++; + for(ib = 0; ib < (width & PIM); ib++) { + /* If the Screen left most bit of the word is set, we're + * starting a box */ + if(w & mask0) { + if(!fInBox) { + rx1 = base + ib; + /* start new box */ + fInBox = TRUE; + } + } else { + if(fInBox) { + /* end box */ + ADDRECT(pReg, rects, FirstRect, + rx1, h, base + ib, h + 1); + fInBox = FALSE; + } + } + /* Shift the word VISUALLY left one. */ + w = SCRLEFT(w, 1); + } + } + /* If scanline ended with last bit set, end the box */ + if(fInBox) { + ADDRECT(pReg, rects, FirstRect, + rx1, h, base + (width & PIM), h + 1); + } + /* if all rectangles on this line have the same x-coords as + * those on the previous line, then add 1 to all the previous y2s and + * throw away all the rectangles from this line + */ + fSame = FALSE; + if(irectPrevStart != -1) { + crects = irectLineStart - irectPrevStart; + if(crects == ((rects - FirstRect) - irectLineStart)) { + prectO = FirstRect + irectPrevStart; + prectN = prectLineStart = FirstRect + irectLineStart; + fSame = TRUE; + while(prectO < prectLineStart) { + if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2)) { + fSame = FALSE; + break; + } + prectO++; + prectN++; + } + if (fSame) { + prectO = FirstRect + irectPrevStart; + while(prectO < prectLineStart) { + prectO->y2 += 1; + prectO++; + } + rects -= crects; + pReg->data->numRects -= crects; + } + } + } + if(!fSame) + irectPrevStart = irectLineStart; + } + if (!pReg->data->numRects) + pReg->extents.x1 = pReg->extents.x2 = 0; + else + { + pReg->extents.y1 = REGION_BOXPTR(pReg)->y1; + pReg->extents.y2 = REGION_END(pReg)->y2; + if (pReg->data->numRects == 1) { + xfree(pReg->data); + pReg->data = (RegDataPtr)NULL; + } + } +#ifdef DEBUG + if (!miValidRegion(pReg)) + FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); +#endif + return(pReg); +} diff --git a/afb/afbcmap.c b/afb/afbcmap.c new file mode 100644 index 000000000..e56558972 --- /dev/null +++ b/afb/afbcmap.c @@ -0,0 +1,121 @@ +/* $XFree86: xc/programs/Xserver/afb/afbcmap.c,v 3.1 1998/11/22 10:36:58 dawes Exp $ */ +/* $XConsortium: afbcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */ +/************************************************************ +Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright no- +tice appear in all copies and that both that copyright no- +tice and this permission notice appear in supporting docu- +mentation, and that the names of Sun or X Consortium +not be used in advertising or publicity pertaining to +distribution of the software without specific prior +written permission. Sun and X Consortium make no +representations about the suitability of this software for +any purpose. It is provided "as is" without any express or +implied warranty. + +SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- +ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#include "X.h" +#include "Xproto.h" +#include "scrnintstr.h" +#include "colormapst.h" +#include "resource.h" +#include "micmap.h" + +int +afbListInstalledColormaps(pScreen, pmaps) + ScreenPtr pScreen; + Colormap *pmaps; +{ + return miListInstalledColormaps(pScreen, pmaps); +} + + +void +afbInstallColormap(pmap) + ColormapPtr pmap; +{ + miInstallColormap(pmap); +} + +void +afbUninstallColormap(pmap) + ColormapPtr pmap; +{ + miUninstallColormap(pmap); +} + +void +afbResolveColor(pred, pgreen, pblue, pVisual) + unsigned short *pred, *pgreen, *pblue; + register VisualPtr pVisual; +{ + miResolveColor(pred, pgreen, pblue, pVisual); +} + +Bool +afbInitializeColormap(pmap) + register ColormapPtr pmap; +{ + return miInitializeColormap(pmap); +} + +int +afbExpandDirectColors(pmap, ndef, indefs, outdefs) + ColormapPtr pmap; + int ndef; + xColorItem *indefs, *outdefs; +{ + return miExpandDirectColors(pmap, ndef, indefs, outdefs); +} + +Bool +afbCreateDefColormap(pScreen) + ScreenPtr pScreen; +{ + return miCreateDefColormap(pScreen); +} + +Bool +afbSetVisualTypes(depth, visuals, bitsPerRGB) + int depth; + int visuals; + int bitsPerRGB; +{ + return miSetVisualTypes(depth, visuals, bitsPerRGB, -1); +} + +/* + * Given a list of formats for a screen, create a list + * of visuals and depths for the screen which correspond to + * the set which can be used with this version of afb. + */ + +Bool +afbInitVisuals(visualp, depthp, nvisualp, ndepthp, rootDepthp, defaultVisp, + sizes, bitsPerRGB) + VisualPtr *visualp; + DepthPtr *depthp; + int *nvisualp, *ndepthp; + int *rootDepthp; + VisualID *defaultVisp; + unsigned long sizes; + int bitsPerRGB; +{ + return miInitVisuals(visualp, depthp, nvisualp, ndepthp, rootDepthp, + defaultVisp, sizes, bitsPerRGB, -1); +} diff --git a/afb/afbfillarc.c b/afb/afbfillarc.c new file mode 100644 index 000000000..a05c32228 --- /dev/null +++ b/afb/afbfillarc.c @@ -0,0 +1,355 @@ +/* $XFree86: xc/programs/Xserver/afb/afbfillarc.c,v 3.1 1998/03/20 21:04:54 hohndel Exp $ */ +/************************************************************ + +Copyright (c) 1989 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +********************************************************/ + +/* $XConsortium: afbfillarc.c,v 5.14 94/04/17 20:28:20 dpw Exp $ */ + +#include "X.h" +#include "Xprotostr.h" +#include "miscstruct.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "afb.h" +#include "maskbits.h" +#include "mifillarc.h" +#include "mi.h" + +static void +afbFillEllipseSolid(pDraw, arc, rrops) + DrawablePtr pDraw; + xArc *arc; + register unsigned char *rrops; +{ + int x, y, e; + int yk, xk, ym, xm, dx, dy, xorg, yorg; + register int slw; + miFillArcRec info; + PixelType *addrlt, *addrlb; + register PixelType *pdst; + PixelType *addrl; + register int n; + register int d; + int nlwidth; + register int xpos; + PixelType startmask, endmask; + int nlmiddle; + int depthDst; + int sizeDst; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + addrlt); + miFillArcSetup(arc, &info); + MIFILLARCSETUP(); + xorg += pDraw->x; + yorg += pDraw->y; + addrlb = addrlt; + addrlt += nlwidth * (yorg - y); + addrlb += nlwidth * (yorg + y + dy); + while (y) { + addrlt += nlwidth; + addrlb -= nlwidth; + MIFILLARCSTEP(slw); + if (!slw) + continue; + xpos = xorg - x; + pdst = addrl = afbScanlineOffset(addrlt, (xpos >> PWSH)); + if (((xpos & PIM) + slw) < PPW) { + maskpartialbits(xpos, slw, startmask); + for (d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */ + switch (rrops[d]) { + case RROP_BLACK: + *pdst &= ~startmask; + break; + case RROP_WHITE: + *pdst |= startmask; + break; + case RROP_INVERT: + *pdst ^= startmask; + break; + case RROP_NOP: + break; + } + } + if (miFillArcLower(slw)) { + pdst = afbScanlineOffset(addrlb, (xpos >> PWSH)); + + for (d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */ + switch (rrops[d]) { + case RROP_BLACK: + *pdst &= ~startmask; + break; + case RROP_WHITE: + *pdst |= startmask; + break; + case RROP_INVERT: + *pdst ^= startmask; + break; + case RROP_NOP: + break; + } + } + } + continue; + } + maskbits(xpos, slw, startmask, endmask, nlmiddle); + for (d = 0; d < depthDst; d++, addrl += sizeDst) { /* @@@ NEXT PLANE @@@ */ + n = nlmiddle; + pdst = addrl; + + switch (rrops[d]) { + case RROP_BLACK: + if (startmask) + *pdst++ &= ~startmask; + while (n--) + *pdst++ = 0; + if (endmask) + *pdst &= ~endmask; + break; + + case RROP_WHITE: + if (startmask) + *pdst++ |= startmask; + while (n--) + *pdst++ = ~0; + if (endmask) + *pdst |= endmask; + break; + + case RROP_INVERT: + if (startmask) + *pdst++ ^= startmask; + while (n--) + *pdst++ ^= ~0; + if (endmask) + *pdst ^= endmask; + break; + + case RROP_NOP: + break; + } + } + if (!miFillArcLower(slw)) + continue; + addrl = afbScanlineOffset(addrlb, (xpos >> PWSH)); + for (d = 0; d < depthDst; d++, addrl += sizeDst) { /* @@@ NEXT PLANE @@@ */ + n = nlmiddle; + pdst = addrl; + + switch (rrops[d]) { + case RROP_BLACK: + if (startmask) + *pdst++ &= ~startmask; + while (n--) + *pdst++ = 0; + if (endmask) + *pdst &= ~endmask; + break; + + case RROP_WHITE: + if (startmask) + *pdst++ |= startmask; + while (n--) + *pdst++ = ~0; + if (endmask) + *pdst |= endmask; + break; + + case RROP_INVERT: + if (startmask) + *pdst++ ^= startmask; + while (n--) + *pdst++ ^= ~0; + if (endmask) + *pdst ^= endmask; + break; + + case RROP_NOP: + break; + } + } + } +} + +#define FILLSPAN(xl,xr,addr) \ + if (xr >= xl) { \ + width = xr - xl + 1; \ + addrl = afbScanlineOffset(addr, (xl >> PWSH)); \ + if (((xl & PIM) + width) < PPW) { \ + maskpartialbits(xl, width, startmask); \ + for (pdst = addrl, d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */ \ + switch (rrops[d]) { \ + case RROP_BLACK: \ + *pdst &= ~startmask; \ + break; \ + case RROP_WHITE: \ + *pdst |= startmask; \ + break; \ + case RROP_INVERT: \ + *pdst ^= startmask; \ + break; \ + case RROP_NOP: \ + break; \ + } \ + } \ + } else { \ + maskbits(xl, width, startmask, endmask, nlmiddle); \ + for (d = 0; d < depthDst; d++, addrl += sizeDst) { /* @@@ NEXT PLANE @@@ */ \ + n = nlmiddle; \ + pdst = addrl; \ + switch (rrops[d]) { \ + case RROP_BLACK: \ + if (startmask) \ + *pdst++ &= ~startmask; \ + while (n--) \ + *pdst++ = 0; \ + if (endmask) \ + *pdst &= ~endmask; \ + break; \ + case RROP_WHITE: \ + if (startmask) \ + *pdst++ |= startmask; \ + while (n--) \ + *pdst++ = ~0; \ + if (endmask) \ + *pdst |= endmask; \ + break; \ + case RROP_INVERT: \ + if (startmask) \ + *pdst++ ^= startmask; \ + while (n--) \ + *pdst++ ^= ~0; \ + if (endmask) \ + *pdst ^= endmask; \ + break; \ + case RROP_NOP: \ + break; \ + } \ + } \ + } \ + } + +#define FILLSLICESPANS(flip,addr) \ + if (!flip) { \ + FILLSPAN(xl, xr, addr); \ + } else { \ + xc = xorg - x; \ + FILLSPAN(xc, xr, addr); \ + xc += slw - 1; \ + FILLSPAN(xl, xc, addr); \ + } + +static void +afbFillArcSliceSolidCopy(pDraw, pGC, arc, rrops) + DrawablePtr pDraw; + GCPtr pGC; + xArc *arc; + register unsigned char *rrops; +{ + PixelType *addrl; + register PixelType *pdst; + register int n; + register int d; + int yk, xk, ym, xm, dx, dy, xorg, yorg, slw; + register int x, y, e; + miFillArcRec info; + miArcSliceRec slice; + int xl, xr, xc; + PixelType *addrlt, *addrlb; + int nlwidth; + int width; + PixelType startmask, endmask; + int nlmiddle; + int sizeDst; + int depthDst; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + addrlt); + miFillArcSetup(arc, &info); + miFillArcSliceSetup(arc, &slice, pGC); + MIFILLARCSETUP(); + xorg += pDraw->x; + yorg += pDraw->y; + addrlb = addrlt; + addrlt = afbScanlineDeltaNoBankSwitch(addrlt, yorg - y, nlwidth); + addrlb = afbScanlineDeltaNoBankSwitch(addrlb, yorg + y + dy, nlwidth); + slice.edge1.x += pDraw->x; + slice.edge2.x += pDraw->x; + while (y > 0) { + afbScanlineIncNoBankSwitch(addrlt, nlwidth); + afbScanlineIncNoBankSwitch(addrlb, -nlwidth); + MIFILLARCSTEP(slw); + MIARCSLICESTEP(slice.edge1); + MIARCSLICESTEP(slice.edge2); + if (miFillSliceUpper(slice)) { + MIARCSLICEUPPER(xl, xr, slice, slw); + FILLSLICESPANS(slice.flip_top, addrlt); + } + if (miFillSliceLower(slice)) { + MIARCSLICELOWER(xl, xr, slice, slw); + FILLSLICESPANS(slice.flip_bot, addrlb); + } + } +} + +void +afbPolyFillArcSolid(pDraw, pGC, narcs, parcs) + register DrawablePtr pDraw; + GCPtr pGC; + int narcs; + xArc *parcs; +{ + afbPrivGC *priv; + register xArc *arc; + register int i; + BoxRec box; + RegionPtr cclip; + unsigned char *rrops; + + priv = (afbPrivGC *) pGC->devPrivates[afbGCPrivateIndex].ptr; + rrops = priv->rrops; + cclip = pGC->pCompositeClip; + for (arc = parcs, i = narcs; --i >= 0; arc++) { + if (miFillArcEmpty(arc)) + continue; + if (miCanFillArc(arc)) { + box.x1 = arc->x + pDraw->x; + box.y1 = arc->y + pDraw->y; + box.x2 = box.x1 + (int)arc->width + 1; + box.y2 = box.y1 + (int)arc->height + 1; + if (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) { + if ((arc->angle2 >= FULLCIRCLE) || + (arc->angle2 <= -FULLCIRCLE)) + afbFillEllipseSolid(pDraw, arc, rrops); + else + afbFillArcSliceSolidCopy(pDraw, pGC, arc, rrops); + continue; + } + } + miPolyFillArc(pDraw, pGC, 1, arc); + } +} diff --git a/afb/afbfillrct.c b/afb/afbfillrct.c new file mode 100644 index 000000000..4d93c2634 --- /dev/null +++ b/afb/afbfillrct.c @@ -0,0 +1,293 @@ +/* $XFree86: xc/programs/Xserver/afb/afbfillrct.c,v 3.1 1998/03/20 21:04:54 hohndel Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbfillrct.c,v 5.10 94/04/17 20:28:21 dpw Exp $ */ + +#include "X.h" +#include "Xprotostr.h" +#include "pixmapstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "miscstruct.h" +#include "regionstr.h" +#include "scrnintstr.h" + +#include "afb.h" +#include "maskbits.h" + +#define MODEQ(a, b) ((a) %= (b)) +void afbPaintOddSize(); + +/* + filled rectangles. + translate the rectangles, clip them, and call the +helper function in the GC. +*/ + +#define NUM_STACK_RECTS 1024 + +void +afbPolyFillRect(pDrawable, pGC, nrectFill, prectInit) + DrawablePtr pDrawable; + GCPtr pGC; + int nrectFill; /* number of rectangles to fill */ + xRectangle *prectInit; /* Pointer to first rectangle to fill */ +{ + xRectangle *prect; + RegionPtr prgnClip; + register BoxPtr pbox; + register BoxPtr pboxClipped; + BoxPtr pboxClippedBase; + BoxPtr pextent; + BoxRec stackRects[NUM_STACK_RECTS]; + int numRects; + int n; + int xorg, yorg; + afbPrivGC *priv; + PixmapPtr ppix; + unsigned char *rrops; + unsigned char *rropsOS; + + priv = (afbPrivGC *)pGC->devPrivates[afbGCPrivateIndex].ptr; + ppix = pGC->pRotatedPixmap; + prgnClip = pGC->pCompositeClip; + rrops = priv->rrops; + rropsOS = priv->rropOS; + + prect = prectInit; + xorg = pDrawable->x; + yorg = pDrawable->y; + if (xorg || yorg) { + prect = prectInit; + n = nrectFill; + Duff(n, prect->x += xorg; prect->y += yorg; prect++); + } + + prect = prectInit; + + numRects = REGION_NUM_RECTS(prgnClip) * nrectFill; + if (numRects > NUM_STACK_RECTS) { + pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec)); + if (!pboxClippedBase) + return; + } + else + pboxClippedBase = stackRects; + + pboxClipped = pboxClippedBase; + + if (REGION_NUM_RECTS(prgnClip) == 1) { + int x1, y1, x2, y2, bx2, by2; + + pextent = REGION_RECTS(prgnClip); + x1 = pextent->x1; + y1 = pextent->y1; + x2 = pextent->x2; + y2 = pextent->y2; + while (nrectFill--) { + if ((pboxClipped->x1 = prect->x) < x1) + pboxClipped->x1 = x1; + + if ((pboxClipped->y1 = prect->y) < y1) + pboxClipped->y1 = y1; + + bx2 = (int) prect->x + (int) prect->width; + if (bx2 > x2) + bx2 = x2; + pboxClipped->x2 = bx2; + + by2 = (int) prect->y + (int) prect->height; + if (by2 > y2) + by2 = y2; + pboxClipped->y2 = by2; + + prect++; + if ((pboxClipped->x1 < pboxClipped->x2) && + (pboxClipped->y1 < pboxClipped->y2)) { + pboxClipped++; + } + } + } else { + int x1, y1, x2, y2, bx2, by2; + + pextent = REGION_EXTENTS(pGC->pScreen, prgnClip); + x1 = pextent->x1; + y1 = pextent->y1; + x2 = pextent->x2; + y2 = pextent->y2; + while (nrectFill--) { + BoxRec box; + + if ((box.x1 = prect->x) < x1) + box.x1 = x1; + + if ((box.y1 = prect->y) < y1) + box.y1 = y1; + + bx2 = (int) prect->x + (int) prect->width; + if (bx2 > x2) + bx2 = x2; + box.x2 = bx2; + + by2 = (int) prect->y + (int) prect->height; + if (by2 > y2) + by2 = y2; + box.y2 = by2; + + prect++; + + if ((box.x1 >= box.x2) || (box.y1 >= box.y2)) + continue; + + n = REGION_NUM_RECTS (prgnClip); + pbox = REGION_RECTS(prgnClip); + + /* clip the rectangle to each box in the clip region + this is logically equivalent to calling Intersect() + */ + while(n--) { + pboxClipped->x1 = max(box.x1, pbox->x1); + pboxClipped->y1 = max(box.y1, pbox->y1); + pboxClipped->x2 = min(box.x2, pbox->x2); + pboxClipped->y2 = min(box.y2, pbox->y2); + pbox++; + + /* see if clipping left anything */ + if(pboxClipped->x1 < pboxClipped->x2 && + pboxClipped->y1 < pboxClipped->y2) { + pboxClipped++; + } + } + } + } + if (pboxClipped != pboxClippedBase) { + switch (pGC->fillStyle) { + case FillSolid: + afbSolidFillArea(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, rrops); + break; + case FillTiled: + switch (pGC->alu) { + case GXcopy: + if (pGC->pRotatedPixmap) + afbTileAreaPPWCopy(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, GXcopy, + pGC->pRotatedPixmap, pGC->planemask); + else + afbTileAreaCopy (pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, GXcopy, + pGC->tile.pixmap, + pGC->patOrg.x, pGC->patOrg.y, + pGC->planemask); + break; + + default: + if (pGC->pRotatedPixmap) + afbTileAreaPPWGeneral(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, pGC->alu, + pGC->pRotatedPixmap, + pGC->planemask); + else + afbTileAreaGeneral(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, pGC->alu, + pGC->tile.pixmap, + pGC->patOrg.x, pGC->patOrg.y, + pGC->planemask); + break; + } /* switch (alu) */ + break; + + case FillStippled: + if (pGC->pRotatedPixmap) + afbStippleAreaPPW(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, pGC->pRotatedPixmap, rrops); + else + afbStippleArea(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, pGC->stipple, + pGC->patOrg.x, pGC->patOrg.y, rrops); + break; + + case FillOpaqueStippled: + switch (pGC->alu) { + case GXcopy: + if (pGC->pRotatedPixmap) + afbOpaqueStippleAreaPPWCopy(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, GXcopy, + pGC->pRotatedPixmap, + rropsOS, pGC->planemask); + else + afbOpaqueStippleAreaCopy(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, GXcopy, + pGC->stipple, + pGC->patOrg.x, pGC->patOrg.y, rropsOS, + pGC->planemask); + break; + + default: + if (pGC->pRotatedPixmap) + afbOpaqueStippleAreaPPWGeneral(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, pGC->alu, + pGC->pRotatedPixmap, + rropsOS, + pGC->planemask); + else + afbOpaqueStippleAreaGeneral(pDrawable, pboxClipped-pboxClippedBase, + pboxClippedBase, pGC->alu, + pGC->stipple, + pGC->patOrg.x, pGC->patOrg.y, + rropsOS, + pGC->planemask); + break; + } /* switch (alu) */ + break; + } + } + if (pboxClippedBase != stackRects) + DEALLOCATE_LOCAL(pboxClippedBase); +} diff --git a/afb/afbfillsp.c b/afb/afbfillsp.c new file mode 100644 index 000000000..69985aebc --- /dev/null +++ b/afb/afbfillsp.c @@ -0,0 +1,1127 @@ +/* $XFree86: xc/programs/Xserver/afb/afbfillsp.c,v 3.4 2001/10/28 03:32:58 tsi Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbfillsp.c,v 5.13 94/04/17 20:28:21 dpw Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "gcstruct.h" +#include "window.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "afb.h" + +#include "maskbits.h" + +#include "mergerop.h" + +#include "servermd.h" +#include "mi.h" +#include "mispans.h" + +/* scanline filling for monochrome frame buffer + written by drewry, oct 1986 + + these routines all clip. they assume that anything that has called +them has already translated the points (i.e. pGC->miTranslate is +non-zero, which is howit gets set in afbCreateGC().) + + the number of new scnalines created by clipping == +MaxRectsPerBand * nSpans. + +*/ + + +void +afbSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GCPtr pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + register DDXPointPtr ppt; /* pointer to list of start points */ + register int *pwidth; /* pointer to list of n widths */ + PixelType *addrlBase; /* pointer to start of bitmap */ + PixelType *pBase; + int nlwidth; /* width in longwords of bitmap */ + register PixelType *addrl;/* pointer to current longword in bitmap */ + register int nlmiddle; + register PixelType startmask; + register PixelType endmask; + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + int depthDst; + int sizeDst; + int d; + unsigned char *rrops; + + n = nInit * miFindMaxBand(pGC->pCompositeClip); + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + pBase); + rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops; + while (n--) { + addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth); + + for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + if (*pwidth) { + addrl = addrlBase; + + switch (rrops[d]) { + case RROP_BLACK: + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + /* all bits inside same longword */ + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl &= ~startmask; + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) + *addrl++ &= ~startmask; + Duff (nlmiddle, *addrl++ = 0x0); + if (endmask) + *addrl &= ~endmask; + } + break; + + case RROP_WHITE: + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + /* all bits inside same longword */ + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl |= startmask; + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) + *addrl++ |= startmask; + Duff (nlmiddle, *addrl++ = ~0); + if (endmask) + *addrl |= endmask; + } + break; + case RROP_INVERT: + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + /* all bits inside same longword */ + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl ^= startmask; + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) + *addrl++ ^= startmask; + Duff (nlmiddle, *addrl++ ^= ~0); + if (endmask) + *addrl ^= endmask; + } + break; + case RROP_NOP: + break; + } + } + } + pwidth++; + ppt++; + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +void +afbStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GC *pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + register DDXPointPtr ppt; /* pointer to list of start points */ + register int *pwidth; /* pointer to list of n widths */ + PixelType *addrlBase; /* pointer to start of bitmap */ + PixelType *pBase; + int nlwidth; /* width in longwords of bitmap */ + register PixelType *addrl;/* pointer to current longword in bitmap */ + register PixelType src; + register int nlmiddle; + register PixelType startmask; + register PixelType endmask; + PixmapPtr pStipple; + PixelType *psrc; + int tileHeight; + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + int d; + int depthDst; + int sizeDst; + unsigned char *rrops; + + n = nInit * miFindMaxBand(pGC->pCompositeClip); + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + pBase); + + pStipple = pGC->pRotatedPixmap; + tileHeight = pStipple->drawable.height; + psrc = (PixelType *)(pStipple->devPrivate.ptr); + + rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops; + + while (n--) { + src = psrc[ppt->y % tileHeight]; + addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth); + for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + addrl = addrlBase; + + switch (rrops[d]) { + case RROP_BLACK: + /* all bits inside same longword */ + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl &= ~(src & startmask); + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) + *addrl++ &= ~(src & startmask); + Duff (nlmiddle, *addrl++ &= ~src); + if (endmask) + *addrl &= ~(src & endmask); + } + break; + case RROP_WHITE: + /* all bits inside same longword */ + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl |= (src & startmask); + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) + *addrl++ |= (src & startmask); + Duff (nlmiddle, *addrl++ |= src); + if (endmask) + *addrl |= (src & endmask); + } + break; + case RROP_INVERT: + /* all bits inside same longword */ + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl ^= (src & startmask); + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) + *addrl++ ^= (src & startmask); + Duff (nlmiddle, *addrl++ ^= src); + if (endmask) + *addrl ^= (src & endmask); + } + break; + + case RROP_NOP: + break; + } + } + pwidth++; + ppt++; + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +void +afbTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GC *pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + register DDXPointPtr ppt; /* pointer to list of start points */ + register int *pwidth; /* pointer to list of n widths */ + PixelType *addrlBase; /* pointer to start of bitmap */ + PixelType *pBase; + int nlwidth; /* width in longwords of bitmap */ + register PixelType *addrl; /* pointer to current longword in bitmap */ + register PixelType src; + register int nlmiddle; + register PixelType startmask; + register PixelType endmask; + PixmapPtr pTile; + PixelType *psrc; + int tileHeight; + int rop; + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + int sizeDst; + int depthDst; + int d; + + n = nInit * miFindMaxBand(pGC->pCompositeClip); + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + pBase); + + pTile = pGC->pRotatedPixmap; + tileHeight = pTile->drawable.height; + psrc = (PixelType *)(pTile->devPrivate.ptr); + rop = pGC->alu; + + switch(rop) { + case GXcopy: +#define DoMaskCopyRop(src,dst,mask) (((dst) & ~(mask)) | ((src) & (mask))) + while (n--) { + if (*pwidth) { + addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth); + + for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + if (!(pGC->planemask & (1 << d))) + continue; + + addrl = addrlBase; + src = psrc[ppt->y % tileHeight + tileHeight * d]; + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl = DoMaskCopyRop (src, *addrl, startmask); + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) { + *addrl = DoMaskCopyRop (src, *addrl, startmask); + addrl++; + } + while (nlmiddle--) { + *addrl = src; + addrl++; + } + if (endmask) + *addrl = DoMaskCopyRop (src, *addrl, endmask); + } + } + } + pwidth++; + ppt++; + } + break; + + default: + { + register DeclareMergeRop (); + + InitializeMergeRop(rop,~0); + while (n--) { + if (*pwidth) { + addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth); + for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + if (!(pGC->planemask & (1 << d))) + continue; + + addrl = addrlBase; + + src = psrc[ppt->y % tileHeight + tileHeight * d]; + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl = DoMaskMergeRop (src, *addrl, startmask); + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) { + *addrl = DoMaskMergeRop (src, *addrl, startmask); + addrl++; + } + while (nlmiddle--) { + *addrl = DoMergeRop (src, *addrl); + addrl++; + } + if (endmask) + *addrl = DoMaskMergeRop (src, *addrl, endmask); + } + } + } + pwidth++; + ppt++; + } + break; + } + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +void +afbOpaqueStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GC *pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + register DDXPointPtr ppt; /* pointer to list of start points */ + register int *pwidth; /* pointer to list of n widths */ + PixelType *addrlBase; /* pointer to start of bitmap */ + PixelType *pBase; + int nlwidth; /* width in longwords of bitmap */ + register PixelType *addrl; /* pointer to current longword in bitmap */ + register PixelType src = 0; + register int nlmiddle; + register PixelType startmask; + register PixelType endmask; + PixmapPtr pTile; + PixelType *psrc; + int tileHeight; + int rop; + unsigned char *rropsOS; + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + int sizeDst; + int depthDst; + int d; + + n = nInit * miFindMaxBand(pGC->pCompositeClip); + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + pBase); + + pTile = pGC->pRotatedPixmap; + tileHeight = pTile->drawable.height; + psrc = (PixelType *)(pTile->devPrivate.ptr); + rop = pGC->alu; + rropsOS = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rropOS; + + switch(rop) { + case GXcopy: + while (n--) { + addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth); + if (*pwidth) { + for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + switch (rropsOS[d]) { + case RROP_BLACK: + src = 0; + break; + case RROP_WHITE: + src = ~0; + break; + case RROP_INVERT: + src = ~psrc[ppt->y % tileHeight]; + break; + case RROP_COPY: + src = psrc[ppt->y % tileHeight]; + break; + case RROP_NOP: + continue; + } + + addrl = addrlBase; + + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl = DoMaskCopyRop (src, *addrl, startmask); + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) { + *addrl = DoMaskCopyRop (src, *addrl, startmask); + addrl++; + } + while (nlmiddle--) { + *addrl = src; + addrl++; + } + if (endmask) + *addrl = DoMaskCopyRop (src, *addrl, endmask); + } + } /* for (d = ...) */ + } + + pwidth++; + ppt++; + } + break; + + default: + { + register DeclareMergeRop (); + + InitializeMergeRop(rop,~0); + while (n--) { + addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth); + if (*pwidth) { + for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + switch (rropsOS[d]) { + case RROP_BLACK: + src = 0; + break; + case RROP_WHITE: + src = ~0; + break; + case RROP_INVERT: + src = ~psrc[ppt->y % tileHeight]; + break; + case RROP_COPY: + src = psrc[ppt->y % tileHeight]; + break; + case RROP_NOP: + continue; + } + + addrl = addrlBase; + + if ( ((ppt->x & PIM) + *pwidth) < PPW) { + maskpartialbits(ppt->x, *pwidth, startmask); + *addrl = DoMaskMergeRop (src, *addrl, startmask); + } else { + maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); + if (startmask) { + *addrl = DoMaskMergeRop (src, *addrl, startmask); + addrl++; + } + while (nlmiddle--) { + *addrl = DoMergeRop (src, *addrl); + addrl++; + } + if (endmask) + *addrl = DoMaskMergeRop (src, *addrl, endmask); + } + } /* for (d = ...) */ + } + pwidth++; + ppt++; + } /* while (n) */ + break; + } + } /* switch (rop) */ + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +/* Fill spans with tiles that aren't PPW bits wide */ +void +afbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GC *pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + int iline; /* first line of tile to use */ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + register DDXPointPtr ppt; /* pointer to list of start points */ + register int *pwidth; /* pointer to list of n widths */ + PixelType *addrlBase; /* pointer to start of bitmap */ + PixelType *pBase; + int nlwidth; /* width in longwords of bitmap */ + register PixelType *pdst;/* pointer to current word in bitmap */ + register PixelType *psrc;/* pointer to current word in tile */ + register int nlMiddle; + register int rop, nstart; + PixelType startmask; + PixmapPtr pTile; /* pointer to tile we want to fill with */ + int w, width, x, xSrc, ySrc, srcStartOver, nend; + int tlwidth, rem, tileWidth, tileHeight, endinc; + PixelType endmask, *psrcT; + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + int sizeDst; + int sizeTile; + int depthDst; + register int d; + + n = nInit * miFindMaxBand(pGC->pCompositeClip); + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + pTile = pGC->tile.pixmap; + tlwidth = pTile->devKind / PGSZB; + rop = pGC->alu; + + xSrc = pDrawable->x; + ySrc = pDrawable->y; + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + pBase); + + tileWidth = pTile->drawable.width; + tileHeight = pTile->drawable.height; + sizeTile = tlwidth * tileHeight; + + /* this replaces rotating the tile. Instead we just adjust the offset + * at which we start grabbing bits from the tile. + * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0, + * so that iline and rem always stay within the tile bounds. + */ + xSrc += (pGC->patOrg.x % tileWidth) - tileWidth; + ySrc += (pGC->patOrg.y % tileHeight) - tileHeight; + + while (n--) { + iline = (ppt->y - ySrc) % tileHeight; + psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth); + addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth); + + for (d = 0; d < depthDst; d++, psrcT += sizeTile, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + if (!(pGC->planemask & (1 << d))) + continue; + + if (*pwidth) { + x = ppt->x; + pdst = addrlBase; + width = *pwidth; + while(width > 0) { + psrc = psrcT; + w = min(tileWidth, width); + if((rem = (x - xSrc) % tileWidth) != 0) { + /* if we're in the middle of the tile, get + as many bits as will finish the span, or + as many as will get to the left edge of the tile, + or a longword worth, starting at the appropriate + offset in the tile. + */ + w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD); + endinc = rem / BITMAP_SCANLINE_PAD; + getandputrop((psrc+endinc), (rem&PIM), (x & PIM), w, pdst, rop); + if((x & PIM) + w >= PPW) + pdst++; + } else if(((x & PIM) + w) < PPW) { + /* doing < PPW bits is easy, and worth special-casing */ + putbitsrop(*psrc, x & PIM, w, pdst, rop); + } else { + /* start at the left edge of the tile, + and put down as much as we can + */ + maskbits(x, w, startmask, endmask, nlMiddle); + + if (startmask) + nstart = PPW - (x & PIM); + else + nstart = 0; + if (endmask) + nend = (x + w) & PIM; + else + nend = 0; + + srcStartOver = nstart > PLST; + + if(startmask) { + putbitsrop(*psrc, (x & PIM), nstart, pdst, rop); + pdst++; + if(srcStartOver) + psrc++; + } + + while(nlMiddle--) { + getandputrop0(psrc, nstart, PPW, pdst, rop); + pdst++; + psrc++; + } + if(endmask) { + getandputrop0(psrc, nstart, nend, pdst, rop); + } + } + x += w; + width -= w; + } + } + } + ppt++; + pwidth++; + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +/* Fill spans with stipples that aren't PPW bits wide */ +void +afbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GC *pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + register DDXPointPtr ppt; /* pointer to list of start points */ + register int *pwidth; /* pointer to list of n widths */ + int iline; /* first line of tile to use */ + PixelType *addrlBase; /* pointer to start of bitmap */ + PixelType *pBase; + int nlwidth; /* width in longwords of bitmap */ + register PixelType *pdst; /* pointer to current word in bitmap */ + register PixelType *psrc; /* pointer to current word in tile */ + register int nlMiddle; + register int rop, nstart; + PixelType startmask; + PixmapPtr pTile; /* pointer to tile we want to fill with */ + int w, width, x, xSrc, ySrc, srcStartOver, nend; + PixelType endmask, *psrcT; + int tlwidth, rem, tileWidth, endinc; + int tileHeight; + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + unsigned char *rrops; + register int d; + int sizeDst; + int depthDst; + + n = nInit * miFindMaxBand(pGC->pCompositeClip); + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + pTile = pGC->stipple; + tlwidth = pTile->devKind / PGSZB; + xSrc = pDrawable->x; + ySrc = pDrawable->y; + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + pBase); + + tileWidth = pTile->drawable.width; + tileHeight = pTile->drawable.height; + rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops; + + /* this replaces rotating the stipple. Instead, we just adjust the offset + * at which we start grabbing bits from the stipple. + * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0, + * so that iline and rem always stay within the tile bounds. + */ + xSrc += (pGC->patOrg.x % tileWidth) - tileWidth; + ySrc += (pGC->patOrg.y % tileHeight) - tileHeight; + while (n--) { + iline = (ppt->y - ySrc) % tileHeight; + psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth); + addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth); + + for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + rop = rrops[d]; + if (rop == RROP_NOP) + continue; + + pdst = addrlBase; + x = ppt->x; + + if (*pwidth) { + width = *pwidth; + while(width > 0) { + psrc = psrcT; + w = min(tileWidth, width); + if((rem = (x - xSrc) % tileWidth) != 0) { + /* if we're in the middle of the tile, get + as many bits as will finish the span, or + as many as will get to the left edge of the tile, + or a longword worth, starting at the appropriate + offset in the tile. + */ + w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD); + endinc = rem / BITMAP_SCANLINE_PAD; + getandputrrop((psrc + endinc), (rem & PIM), (x & PIM), + w, pdst, rop) + if((x & PIM) + w >= PPW) + pdst++; + } else if(((x & PIM) + w) < PPW) { + /* doing < PPW bits is easy, and worth special-casing */ + putbitsrrop(*psrc, x & PIM, w, pdst, rop); + } else { + /* start at the left edge of the tile, + and put down as much as we can + */ + maskbits(x, w, startmask, endmask, nlMiddle); + + if (startmask) + nstart = PPW - (x & PIM); + else + nstart = 0; + if (endmask) + nend = (x + w) & PIM; + else + nend = 0; + + srcStartOver = nstart > PLST; + + if(startmask) { + putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop); + pdst++; + if(srcStartOver) + psrc++; + } + + while(nlMiddle--) { + getandputrrop0(psrc, nstart, PPW, pdst, rop); + pdst++; + psrc++; + } + if(endmask) { + getandputrrop0(psrc, nstart, nend, pdst, rop); + } + } + x += w; + width -= w; + } + } + } + ppt++; + pwidth++; + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +/* Fill spans with OpaqueStipples that aren't PPW bits wide */ +void +afbUnnaturalOpaqueStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GC *pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + int iline; /* first line of tile to use */ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + register DDXPointPtr ppt; /* pointer to list of start points */ + register int *pwidth; /* pointer to list of n widths */ + PixelType *addrlBase; /* pointer to start of bitmap */ + PixelType *pBase; + int nlwidth; /* width in longwords of bitmap */ + register PixelType *pdst;/* pointer to current word in bitmap */ + register PixelType *psrc;/* pointer to current word in tile */ + register int nlMiddle; + register int d; + register PixelType tmpsrc = 0; + register PixelType tmpdst; + register int alu, nstart; + register unsigned char *rropsOS; + PixelType startmask; + PixmapPtr pTile; /* pointer to tile we want to fill with */ + int w, width, x, xSrc, ySrc, srcStartOver, nend; + int tlwidth, rem, tileWidth, tileHeight, endinc; + PixelType endmask, *psrcT; + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + int sizeDst; + int depthDst; + + n = nInit * miFindMaxBand(pGC->pCompositeClip); + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + pTile = pGC->stipple; + tlwidth = pTile->devKind / PGSZB; + alu = pGC->alu; + + xSrc = pDrawable->x; + ySrc = pDrawable->y; + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + pBase); + + tileWidth = pTile->drawable.width; + tileHeight = pTile->drawable.height; + rropsOS = afbGetGCPrivate(pGC)->rropOS; + + /* this replaces rotating the tile. Instead we just adjust the offset + * at which we start grabbing bits from the tile. + * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0, + * so that iline and rem always stay within the tile bounds. + */ + xSrc += (pGC->patOrg.x % tileWidth) - tileWidth; + ySrc += (pGC->patOrg.y % tileHeight) - tileHeight; + + while (n--) { + iline = (ppt->y - ySrc) % tileHeight; + psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth); + addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth); + + for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + if (!(pGC->planemask & (1 << d))) + continue; + + if (*pwidth) { + x = ppt->x; + pdst = addrlBase; + width = *pwidth; + while(width > 0) { + psrc = psrcT; + w = min(tileWidth, width); + if((rem = (x - xSrc) % tileWidth) != 0) { + /* if we're in the middle of the tile, get + as many bits as will finish the span, or + as many as will get to the left edge of the tile, + or a longword worth, starting at the appropriate + offset in the tile. + */ + w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD); + endinc = rem / BITMAP_SCANLINE_PAD; + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + + case RROP_COPY: + getbits ((psrc+endinc), (rem&PIM), w, tmpsrc); + break; + + case RROP_INVERT: + getbits ((psrc+endinc), (rem&PIM), w, tmpsrc); + tmpsrc = ~tmpsrc; + break; + } + + if (alu != GXcopy) { + getbits (pdst, (x & PIM), w, tmpdst); + DoRop (tmpsrc, alu, tmpsrc, tmpdst); + } + + putbits (tmpsrc, (x & PIM), w, pdst); + if((x & PIM) + w >= PPW) + pdst++; + } else if(((x & PIM) + w) < PPW) { + /* doing < PPW bits is easy, and worth special-casing */ + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + case RROP_COPY: + tmpsrc = *psrc; + break; + case RROP_INVERT: + tmpsrc = ~*psrc; + break; + } + if (alu != GXcopy) { + getbits (pdst, (x & PIM), w, tmpdst); + DoRop (tmpsrc, alu, tmpsrc, tmpdst); + } + putbits (tmpsrc, (x & PIM), w, pdst); + } else { + /* start at the left edge of the tile, + and put down as much as we can + */ + maskbits(x, w, startmask, endmask, nlMiddle); + + if (startmask) + nstart = PPW - (x & PIM); + else + nstart = 0; + if (endmask) + nend = (x + w) & PIM; + else + nend = 0; + + srcStartOver = nstart > PLST; + + if(startmask) { + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + case RROP_COPY: + tmpsrc = *psrc; + break; + case RROP_INVERT: + tmpsrc = ~*psrc; + break; + } + if (alu != GXcopy) { + getbits (pdst, (x & PIM), nstart, tmpdst); + DoRop (tmpsrc, alu, tmpsrc, tmpdst); + } + putbits (tmpsrc, (x & PIM), nstart, pdst); + pdst++; + if(srcStartOver) + psrc++; + } + + while(nlMiddle--) { + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + case RROP_COPY: + getbits (psrc, nstart, PPW, tmpsrc); + break; + case RROP_INVERT: + getbits (psrc, nstart, PPW, tmpsrc); + tmpsrc = ~tmpsrc; + break; + } + if (alu != GXcopy) { + tmpdst = *pdst; + DoRop (tmpsrc, alu, tmpsrc, tmpdst); + } + *pdst++ = tmpsrc; + /*putbits (tmpsrc, 0, PPW, pdst); + pdst++;*/ + psrc++; + } + if(endmask) { + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + + case RROP_COPY: + getbits (psrc, nstart, nend, tmpsrc); + break; + + case RROP_INVERT: + getbits (psrc, nstart, nend, tmpsrc); + tmpsrc = ~tmpsrc; + break; + } + if (alu != GXcopy) { + tmpdst = *pdst; + DoRop (tmpsrc, alu, tmpsrc, tmpdst); + } + putbits (tmpsrc, 0, nend, pdst); + } + } + x += w; + width -= w; + } + } + } + ppt++; + pwidth++; + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} diff --git a/afb/afbfont.c b/afb/afbfont.c new file mode 100644 index 000000000..0ad8d9de3 --- /dev/null +++ b/afb/afbfont.c @@ -0,0 +1,75 @@ +/* $XFree86: xc/programs/Xserver/afb/afbfont.c,v 3.0 1996/08/18 01:45:35 dawes Exp $ */ +/* + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ +/* $XConsortium: afbfont.c,v 1.18 94/04/17 20:28:22 keith Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "afb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "scrnintstr.h" + +/*ARGSUSED*/ +Bool +afbRealizeFont( pscr, pFont) + ScreenPtr pscr; + FontPtr pFont; +{ + return (TRUE); +} + +/*ARGSUSED*/ +Bool +afbUnrealizeFont( pscr, pFont) + ScreenPtr pscr; + FontPtr pFont; +{ + return (TRUE); +} diff --git a/afb/afbgc.c b/afb/afbgc.c new file mode 100644 index 000000000..fe88475a3 --- /dev/null +++ b/afb/afbgc.c @@ -0,0 +1,707 @@ +/* $XFree86: xc/programs/Xserver/afb/afbgc.c,v 3.3 2001/10/28 03:32:58 tsi Exp $ */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbgc.c,v 5.35 94/04/17 20:28:23 dpw Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "afb.h" +#include "dixfontstr.h" +#include "fontstruct.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "region.h" + +#include "mistruct.h" +#include "migc.h" + +#include "maskbits.h" + +static GCFuncs afbFuncs = { + afbValidateGC, + miChangeGC, + miCopyGC, + afbDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip +}; + +static GCOps afbGCOps = { + afbSolidFS, + afbSetSpans, + afbPutImage, + afbCopyArea, + miCopyPlane, + afbPolyPoint, + afbLineSS, + afbSegmentSS, + miPolyRectangle, + afbZeroPolyArcSS, + afbFillPolygonSolid, + afbPolyFillRect, + afbPolyFillArcSolid, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + afbTEGlyphBlt, + afbPolyGlyphBlt, + afbPushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + + +Bool +afbCreateGC(pGC) + register GCPtr pGC; +{ + afbPrivGC *pPriv; + + pGC->clientClip = NULL; + pGC->clientClipType = CT_NONE; + + /* some of the output primitives aren't really necessary, since + they will be filled in ValidateGC because of dix/CreateGC() + setting all the change bits. Others are necessary because although + they depend on being a monochrome frame buffer, they don't change + */ + + pGC->ops = &afbGCOps; + pGC->funcs = &afbFuncs; + + /* afb wants to translate before scan convesion */ + pGC->miTranslate = 1; + + pPriv = (afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr); + afbReduceRop(pGC->alu, pGC->fgPixel, pGC->planemask, pGC->depth, + pPriv->rrops); + afbReduceOpaqueStipple(pGC->fgPixel, pGC->bgPixel, pGC->planemask, + pGC->depth, pPriv->rropOS); + + pGC->fExpose = TRUE; + pGC->pRotatedPixmap = NullPixmap; + pGC->freeCompClip = FALSE; + return TRUE; +} + +/* Clipping conventions + if the drawable is a window + CT_REGION ==> pCompositeClip really is the composite + CT_other ==> pCompositeClip is the window clip region + if the drawable is a pixmap + CT_REGION ==> pCompositeClip is the translated client region + clipped to the pixmap boundary + CT_other ==> pCompositeClip is the pixmap bounding box +*/ + +/*ARGSUSED*/ +void +afbValidateGC(pGC, changes, pDrawable) + register GCPtr pGC; + unsigned long changes; + DrawablePtr pDrawable; +{ + register afbPrivGCPtr devPriv; + int mask; /* stateChanges */ + int index; /* used for stepping through bitfields */ + int xrot, yrot; /* rotations for tile and stipple pattern */ + /* flags for changing the proc vector + and updating things in devPriv + */ + int new_rotate, new_rrop, new_line, new_text, new_fill; + DDXPointRec oldOrg; /* origin of thing GC was last used with */ + + oldOrg = pGC->lastWinOrg; + + pGC->lastWinOrg.x = pDrawable->x; + pGC->lastWinOrg.y = pDrawable->y; + + /* we need to re-rotate the tile if the previous window/pixmap + origin (oldOrg) differs from the new window/pixmap origin + (pGC->lastWinOrg) + */ + new_rotate = (oldOrg.x != pGC->lastWinOrg.x) || + (oldOrg.y != pGC->lastWinOrg.y); + + + devPriv = ((afbPrivGCPtr)(pGC->devPrivates[afbGCPrivateIndex].ptr)); + + + /* + if the client clip is different or moved OR + the subwindowMode has changed OR + the window's clip has changed since the last validation + we need to recompute the composite clip + */ + if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) || + (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))) + afbComputeCompositeClip(pGC, pDrawable); + + new_rrop = FALSE; + new_line = FALSE; + new_text = FALSE; + new_fill = FALSE; + + mask = changes; + while (mask) { + index = lowbit(mask); + mask &= ~index; + + /* this switch acculmulates a list of which procedures + might have to change due to changes in the GC. in + some cases (e.g. changing one 16 bit tile for another) + we might not really need a change, but the code is + being paranoid. + this sort of batching wins if, for example, the alu + and the font have been changed, or any other pair + of items that both change the same thing. + */ + switch (index) { + case GCPlaneMask: + case GCFunction: + case GCForeground: + new_rrop = TRUE; + break; + case GCBackground: + new_rrop = TRUE; /* for opaque stipples */ + break; + case GCLineStyle: + case GCLineWidth: + case GCJoinStyle: + new_line = TRUE; + break; + case GCCapStyle: + break; + case GCFillStyle: + new_fill = TRUE; + break; + case GCFillRule: + break; + case GCTile: + if(pGC->tileIsPixel) + break; + new_rotate = TRUE; + new_fill = TRUE; + break; + + case GCStipple: + if(pGC->stipple == (PixmapPtr)NULL) + break; + new_rotate = TRUE; + new_fill = TRUE; + break; + + case GCTileStipXOrigin: + new_rotate = TRUE; + break; + + case GCTileStipYOrigin: + new_rotate = TRUE; + break; + + case GCFont: + new_text = TRUE; + break; + case GCSubwindowMode: + break; + case GCGraphicsExposures: + break; + case GCClipXOrigin: + break; + case GCClipYOrigin: + break; + case GCClipMask: + break; + case GCDashOffset: + break; + case GCDashList: + break; + case GCArcMode: + break; + default: + break; + } + } + + /* deal with the changes we've collected . + new_rrop must be done first because subsequent things + depend on it. + */ + + if(new_rotate || new_fill) { + Bool new_pix = FALSE; + + /* figure out how much to rotate */ + xrot = pGC->patOrg.x; + yrot = pGC->patOrg.y; + xrot += pDrawable->x; + yrot += pDrawable->y; + + switch (pGC->fillStyle) { + case FillTiled: + /* copy current tile and stipple */ + if (!pGC->tileIsPixel && + (pGC->tile.pixmap->drawable.width <= PPW) && + !(pGC->tile.pixmap->drawable.width & + (pGC->tile.pixmap->drawable.width - 1))) { + afbCopyRotatePixmap(pGC->tile.pixmap, &pGC->pRotatedPixmap, + xrot, yrot); + new_pix = TRUE; + } + break; + case FillStippled: + case FillOpaqueStippled: + if (pGC->stipple && (pGC->stipple->drawable.width <= PPW) && + !(pGC->stipple->drawable.width & + (pGC->stipple->drawable.width - 1))) { + afbCopyRotatePixmap(pGC->stipple, &pGC->pRotatedPixmap, + xrot, yrot); + new_pix = TRUE; + } + } + /* destroy any previously rotated tile or stipple */ + if (!new_pix && pGC->pRotatedPixmap) { + (*pDrawable->pScreen->DestroyPixmap)(pGC->pRotatedPixmap); + pGC->pRotatedPixmap = (PixmapPtr)NULL; + } + } + + /* + * duck out here when the GC is unchanged + */ + + if (!changes) + return; + + if (new_rrop || new_fill) { + afbReduceRop(pGC->alu, pGC->fgPixel, pGC->planemask, pDrawable->depth, + devPriv->rrops); + afbReduceOpaqueStipple(pGC->fgPixel, pGC->bgPixel, pGC->planemask, + pGC->depth, devPriv->rropOS); + new_fill = TRUE; + } + + if (new_line || new_fill || new_text) { + if (!pGC->ops->devPrivate.val) { + pGC->ops = miCreateGCOps(pGC->ops); + pGC->ops->devPrivate.val = 1; + } + } + + if (new_line || new_fill) { + if (pGC->lineWidth == 0) { + if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid) + pGC->ops->PolyArc = afbZeroPolyArcSS; + else + pGC->ops->PolyArc = miZeroPolyArc; + } else + pGC->ops->PolyArc = miPolyArc; + if (pGC->lineStyle == LineSolid) { + if(pGC->lineWidth == 0) { + if (pGC->fillStyle == FillSolid) { + pGC->ops->PolySegment = afbSegmentSS; + pGC->ops->Polylines = afbLineSS; + } + else + { + pGC->ops->PolySegment = miPolySegment; + pGC->ops->Polylines = miZeroLine; + } + } else { + pGC->ops->PolySegment = miPolySegment; + pGC->ops->Polylines = miWideLine; + } + } else { + if(pGC->lineWidth == 0 && pGC->fillStyle == FillSolid) { + pGC->ops->PolySegment = afbSegmentSD; + pGC->ops->Polylines = afbLineSD; + } else { + pGC->ops->PolySegment = miPolySegment; + pGC->ops->Polylines = miWideDash; + } + } + } + + if (new_text || new_fill) { + if ((pGC->font) && + (FONTMAXBOUNDS(pGC->font,rightSideBearing) - + FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 || + FONTMINBOUNDS(pGC->font,characterWidth) < 0)) { + pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; + pGC->ops->ImageGlyphBlt = miImageGlyphBlt; + } else { + /* special case ImageGlyphBlt for terminal emulator fonts */ + if ((pGC->font) && + TERMINALFONT(pGC->font)) { + pGC->ops->ImageGlyphBlt = afbTEGlyphBlt; + } else { + pGC->ops->ImageGlyphBlt = afbImageGlyphBlt; + } + + /* now do PolyGlyphBlt */ + if (pGC->fillStyle == FillSolid) { + pGC->ops->PolyGlyphBlt = afbPolyGlyphBlt; + } else { + pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; + } + } + } + + if (new_fill) { + /* install a suitable fillspans and pushpixels */ + pGC->ops->PushPixels = afbPushPixels; + pGC->ops->FillPolygon = miFillPolygon; + pGC->ops->PolyFillArc = miPolyFillArc; + + switch (pGC->fillStyle) { + case FillSolid: + pGC->ops->FillSpans = afbSolidFS; + pGC->ops->FillPolygon = afbFillPolygonSolid; + pGC->ops->PolyFillArc = afbPolyFillArcSolid; + break; + case FillTiled: + if (pGC->pRotatedPixmap) + pGC->ops->FillSpans = afbTileFS; + else + pGC->ops->FillSpans = afbUnnaturalTileFS; + break; + case FillOpaqueStippled: + if (pGC->pRotatedPixmap) + pGC->ops->FillSpans = afbOpaqueStippleFS; + else + pGC->ops->FillSpans = afbUnnaturalOpaqueStippleFS; + break; + + case FillStippled: + if (pGC->pRotatedPixmap) + pGC->ops->FillSpans = afbStippleFS; + else + pGC->ops->FillSpans = afbUnnaturalStippleFS; + break; + } + } /* end of new_fill */ +} + +void +afbDestroyGC(pGC) + GCPtr pGC; +{ + if (pGC->pRotatedPixmap) + (*pGC->pScreen->DestroyPixmap)(pGC->pRotatedPixmap); + if (pGC->freeCompClip) + REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip); + miDestroyGCOps(pGC->ops); +} + +/* table to map alu(src, dst) to alu(~src, dst) */ +int afbInverseAlu[16] = { + GXclear, + GXandInverted, + GXnor, + GXcopyInverted, + GXand, + GXnoop, + GXequiv, + GXorInverted, + GXandReverse, + GXxor, + GXinvert, + GXnand, + GXcopy, + GXor, + GXorReverse, + GXset +}; + +void +afbReduceOpaqueStipple(fg, bg, planemask, depth, rop) +register PixelType fg; +register PixelType bg; +register unsigned long planemask; +int depth; +register unsigned char *rop; +{ + register int d; + register Pixel mask = 1; + + bg ^= fg; + + for (d = 0; d < depth; d++, mask <<= 1) { + if (!(planemask & mask)) + rop[d] = RROP_NOP; + else if (!(bg & mask)) { + /* Both fg and bg have a 0 or 1 in this plane */ + if (fg & mask) + rop[d] = RROP_WHITE; + else + rop[d] = RROP_BLACK; + } else { + /* Both fg and bg have different bits on this plane */ + if (fg & mask) + rop[d] = RROP_COPY; + else + rop[d] = RROP_INVERT; + } + } +} + +void +afbReduceRop(alu, src, planemask, depth, rop) + register int alu; + register Pixel src; + register unsigned long planemask; + int depth; + register unsigned char *rop; +{ + register int d; + register Pixel mask = 1; + + for (d = 0; d < depth; d++, mask <<= 1) { + if (!(planemask & mask)) + rop[d] = RROP_NOP; + else if ((src & mask) == 0) /* src is black */ + switch (alu) { + case GXclear: + rop[d] = RROP_BLACK; + break; + case GXand: + rop[d] = RROP_BLACK; + break; + case GXandReverse: + rop[d] = RROP_BLACK; + break; + case GXcopy: + rop[d] = RROP_BLACK; + break; + case GXandInverted: + rop[d] = RROP_NOP; + break; + case GXnoop: + rop[d] = RROP_NOP; + break; + case GXxor: + rop[d] = RROP_NOP; + break; + case GXor: + rop[d] = RROP_NOP; + break; + case GXnor: + rop[d] = RROP_INVERT; + break; + case GXequiv: + rop[d] = RROP_INVERT; + break; + case GXinvert: + rop[d] = RROP_INVERT; + break; + case GXorReverse: + rop[d] = RROP_INVERT; + break; + case GXcopyInverted: + rop[d] = RROP_WHITE; + break; + case GXorInverted: + rop[d] = RROP_WHITE; + break; + case GXnand: + rop[d] = RROP_WHITE; + break; + case GXset: + rop[d] = RROP_WHITE; + break; + } + else /* src is white */ + switch (alu) { + case GXclear: + rop[d] = RROP_BLACK; + break; + case GXand: + rop[d] = RROP_NOP; + break; + case GXandReverse: + rop[d] = RROP_INVERT; + break; + case GXcopy: + rop[d] = RROP_WHITE; + break; + case GXandInverted: + rop[d] = RROP_BLACK; + break; + case GXnoop: + rop[d] = RROP_NOP; + break; + case GXxor: + rop[d] = RROP_INVERT; + break; + case GXor: + rop[d] = RROP_WHITE; + break; + case GXnor: + rop[d] = RROP_BLACK; + break; + case GXequiv: + rop[d] = RROP_NOP; + break; + case GXinvert: + rop[d] = RROP_INVERT; + break; + case GXorReverse: + rop[d] = RROP_WHITE; + break; + case GXcopyInverted: + rop[d] = RROP_BLACK; + break; + case GXorInverted: + rop[d] = RROP_NOP; + break; + case GXnand: + rop[d] = RROP_INVERT; + break; + case GXset: + rop[d] = RROP_WHITE; + break; + } + } +} + +void +afbComputeCompositeClip(pGC, pDrawable) + GCPtr pGC; + DrawablePtr pDrawable; +{ + if (pDrawable->type == DRAWABLE_WINDOW) { + WindowPtr pWin = (WindowPtr) pDrawable; + RegionPtr pregWin; + Bool freeTmpClip, freeCompClip; + + if (pGC->subWindowMode == IncludeInferiors) { + pregWin = NotClippedByChildren(pWin); + freeTmpClip = TRUE; + } else { + pregWin = &pWin->clipList; + freeTmpClip = FALSE; + } + freeCompClip = pGC->freeCompClip; + + /* + * if there is no client clip, we can get by with just keeping the + * pointer we got, and remembering whether or not should destroy (or + * maybe re-use) it later. this way, we avoid unnecessary copying of + * regions. (this wins especially if many clients clip by children + * and have no client clip.) + */ + if (pGC->clientClipType == CT_NONE) { + if (freeCompClip) + REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip); + pGC->pCompositeClip = pregWin; + pGC->freeCompClip = freeTmpClip; + } else { + /* + * we need one 'real' region to put into the composite clip. if + * pregWin the current composite clip are real, we can get rid of + * one. if pregWin is real and the current composite clip isn't, + * use pregWin for the composite clip. if the current composite + * clip is real and pregWin isn't, use the current composite + * clip. if neither is real, create a new region. + */ + + REGION_TRANSLATE(pGC->pScreen, pGC->clientClip, + pDrawable->x + pGC->clipOrg.x, + pDrawable->y + pGC->clipOrg.y); + + if (freeCompClip) { + REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip, pregWin, + pGC->clientClip); + if (freeTmpClip) + REGION_DESTROY(pGC->pScreen, pregWin); + } else if (freeTmpClip) { + REGION_INTERSECT(pGC->pScreen, pregWin, pregWin, pGC->clientClip); + pGC->pCompositeClip = pregWin; + } else { + pGC->pCompositeClip = REGION_CREATE(pGC->pScreen, NullBox, 0); + REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip, + pregWin, pGC->clientClip); + } + pGC->freeCompClip = TRUE; + REGION_TRANSLATE(pGC->pScreen, pGC->clientClip, + -(pDrawable->x + pGC->clipOrg.x), + -(pDrawable->y + pGC->clipOrg.y)); + } + } /* end of composite clip for a window */ + else { + BoxRec pixbounds; + + /* XXX should we translate by drawable.x/y here ? */ + pixbounds.x1 = 0; + pixbounds.y1 = 0; + pixbounds.x2 = pDrawable->width; + pixbounds.y2 = pDrawable->height; + + if (pGC->freeCompClip) { + REGION_RESET(pGC->pScreen, pGC->pCompositeClip, &pixbounds); + } else { + pGC->freeCompClip = TRUE; + pGC->pCompositeClip = REGION_CREATE(pGC->pScreen, &pixbounds, 1); + } + + if (pGC->clientClipType == CT_REGION) { + REGION_TRANSLATE(pGC->pScreen, pGC->pCompositeClip, -pGC->clipOrg.x, + -pGC->clipOrg.y); + REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip, + pGC->pCompositeClip, pGC->clientClip); + REGION_TRANSLATE(pGC->pScreen, pGC->pCompositeClip, pGC->clipOrg.x, + pGC->clipOrg.y); + } + } /* end of composite clip for pixmap */ +} /* end afbComputeCompositeClip */ diff --git a/afb/afbgetsp.c b/afb/afbgetsp.c new file mode 100644 index 000000000..0fa825d21 --- /dev/null +++ b/afb/afbgetsp.c @@ -0,0 +1,163 @@ +/* $XFree86: xc/programs/Xserver/afb/afbgetsp.c,v 3.1 2001/10/28 03:32:58 tsi Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbgetsp.c,v 5.10 94/04/17 20:28:24 dpw Exp $ */ + +#include "X.h" +#include "Xmd.h" + +#include "misc.h" +#include "region.h" +#include "gc.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "afb.h" +#include "maskbits.h" + +#include "servermd.h" + +/* GetSpans -- for each span, gets bits from drawable starting at ppt[i] + * and continuing for pwidth[i] bits + * Each scanline returned will be server scanline padded, i.e., it will come + * out to an integral number of words. + */ +/*ARGSUSED*/ +void +afbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart) + DrawablePtr pDrawable; /* drawable from which to get bits */ + int wMax; /* largest value of all *pwidths */ + register DDXPointPtr ppt; /* points to start copying from */ + int *pwidth; /* list of number of bits to copy */ + int nspans; /* number of scanlines to copy */ + char *pchardstStart; /* where to put the bits */ +{ + PixelType *pdstStart = (PixelType *)pchardstStart; + register PixelType *pdst; /* where to put the bits */ + register PixelType *psrc; /* where to get the bits */ + register PixelType tmpSrc; /* scratch buffer for bits */ + PixelType *psrcBase; /* start of src bitmap */ + int widthSrc; /* width of pixmap in bytes */ + int sizeSrc; + int depthSrc; + register DDXPointPtr pptLast; /* one past last point to get */ + int xEnd; /* last pixel to copy from */ + register int nstart; + register int d; + int nend = 0; + int srcStartOver; + PixelType startmask, endmask; + unsigned int srcBit; + int nlMiddle, nl; + int w; + + pptLast = ppt + nspans; + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, widthSrc, sizeSrc, depthSrc, + psrcBase); + pdst = pdstStart; + + while(ppt < pptLast) { + /* XXX should this really be << PWSH, or * 8, or * PGSZB? */ + xEnd = min(ppt->x + *pwidth, widthSrc << PWSH); + pwidth++; + for (d = 0; d < depthSrc; d++) { + psrc = afbScanline(psrcBase, ppt->x, ppt->y, widthSrc); + psrcBase += sizeSrc; /* @@@ NEXT PLANE @@@ */ + w = xEnd - ppt->x; + srcBit = ppt->x & PIM; + + if (srcBit + w <= PPW) + { + getandputbits0(psrc, srcBit, w, pdst); + pdst++; + } + else + { + + maskbits(ppt->x, w, startmask, endmask, nlMiddle); + if (startmask) + nstart = PPW - srcBit; + else + nstart = 0; + if (endmask) + nend = xEnd & PIM; + srcStartOver = srcBit + nstart > PLST; + if (startmask) + { + getandputbits0(psrc, srcBit, nstart, pdst); + if(srcStartOver) + psrc++; + } + nl = nlMiddle; +#ifdef FASTPUTBITS + Duff(nl, putbits(*psrc, nstart, PPW, pdst); psrc++; pdst++;); +#else + while (nl--) + { + tmpSrc = *psrc; + putbits(tmpSrc, nstart, PPW, pdst); + psrc++; + pdst++; + } +#endif + if (endmask) + { + putbits(*psrc, nstart, nend, pdst); + if(nstart + nend > PPW) + pdst++; + } + if (startmask || endmask) + pdst++; + } + } + ppt++; + } +} diff --git a/afb/afbhrzvert.c b/afb/afbhrzvert.c new file mode 100644 index 000000000..b50c357b4 --- /dev/null +++ b/afb/afbhrzvert.c @@ -0,0 +1,207 @@ +/* $XFree86: xc/programs/Xserver/afb/afbhrzvert.c,v 3.1 2001/08/01 00:44:47 tsi Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbhrzvert.c,v 1.15 94/04/17 20:28:24 dpw Exp $ */ + +#include "X.h" + +#include "gc.h" +#include "window.h" +#include "pixmap.h" +#include "region.h" + +#include "afb.h" +#include "maskbits.h" + +/* horizontal solid line + abs(len) > 1 +*/ +void +afbHorzS(pbase, nlwidth, sizeDst, depthDst, x1, y1, len, rrops) +PixelType *pbase; /* pointer to base of bitmap */ +register int nlwidth; /* width in longwords of bitmap */ +int sizeDst; +int depthDst; +int x1; /* initial point */ +int y1; +int len; /* length of line */ +register unsigned char *rrops; +{ + register PixelType *addrl; + register PixelType startmask; + register PixelType endmask; + register int nlmiddle; + register int d; + int saveNLmiddle; + + /* force the line to go left to right + but don't draw the last point + */ + if (len < 0) { + x1 += len; + x1 += 1; + len = -len; + } + + /* all bits inside same longword */ + if ( ((x1 & PIM) + len) < PPW) { + maskpartialbits(x1, len, startmask); + + for (d = 0; d < depthDst; d++) { + addrl = afbScanline(pbase, x1, y1, nlwidth); + pbase += sizeDst; /* @@@ NEXT PLANE @@@ */ + + switch (rrops[d]) { + case RROP_BLACK: + *addrl &= ~startmask; + break; + case RROP_WHITE: + *addrl |= startmask; + break; + case RROP_INVERT: + *addrl ^= startmask; + break; + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ...) */ + } else { + maskbits(x1, len, startmask, endmask, nlmiddle); + saveNLmiddle = nlmiddle; + + for (d = 0; d < depthDst; d++) { + addrl = afbScanline(pbase, x1, y1, nlwidth); + pbase += sizeDst; /* @@@ NEXT PLANE @@@ */ + nlmiddle = saveNLmiddle; + + switch (rrops[d]) { + case RROP_BLACK: + if (startmask) + *addrl++ &= ~startmask; + Duff (nlmiddle, *addrl++ = 0x0); + if (endmask) + *addrl &= ~endmask; + break; + + case RROP_WHITE: + if (startmask) + *addrl++ |= startmask; + Duff (nlmiddle, *addrl++ = ~0); + if (endmask) + *addrl |= endmask; + break; + + case RROP_INVERT: + if (startmask) + *addrl++ ^= startmask; + Duff (nlmiddle, *addrl++ ^= ~0); + if (endmask) + *addrl ^= endmask; + break; + + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ... ) */ + } +} + +/* vertical solid line + this uses do loops because pcc (Ultrix 1.2, bsd 4.2) generates + better code. sigh. we know that len will never be 0 or 1, so + it's OK to use it. +*/ +void +afbVertS(pbase, nlwidth, sizeDst, depthDst, x1, y1, len, rrops) +PixelType *pbase; /* pointer to base of bitmap */ +register int nlwidth; /* width in longwords of bitmap */ +int sizeDst; +int depthDst; +int x1, y1; /* initial point */ +register int len; /* length of line */ +unsigned char *rrops; +{ + register PixelType *addrl; + register PixelType bitmask; + int saveLen; + int d; + + if (len < 0) { + nlwidth = -nlwidth; + len = -len; + } + + saveLen = len; + + for (d = 0; d < depthDst; d++) { + addrl = afbScanline(pbase, x1, y1, nlwidth); + pbase += sizeDst; /* @@@ NEXT PLANE @@@ */ + len = saveLen; + + switch (rrops[d]) { + case RROP_BLACK: + bitmask = rmask[x1 & PIM]; + Duff(len, *addrl &= bitmask; afbScanlineInc(addrl, nlwidth) ); + break; + + case RROP_WHITE: + bitmask = mask[x1 & PIM]; + Duff(len, *addrl |= bitmask; afbScanlineInc(addrl, nlwidth) ); + break; + + case RROP_INVERT: + bitmask = mask[x1 & PIM]; + Duff(len, *addrl ^= bitmask; afbScanlineInc(addrl, nlwidth) ); + break; + + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ...) */ +} diff --git a/afb/afbimage.c b/afb/afbimage.c new file mode 100644 index 000000000..cfb230e36 --- /dev/null +++ b/afb/afbimage.c @@ -0,0 +1,297 @@ +/* $XFree86: xc/programs/Xserver/afb/afbimage.c,v 3.3 2001/10/28 03:32:58 tsi Exp $ */ + +#include "X.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#include "afb.h" +#include "maskbits.h" +#include "servermd.h" +#include "mfb.h" + +void +afbPutImage(pDraw, pGC, depth, x, y, width, height, leftPad, format, pImage) + DrawablePtr pDraw; + GCPtr pGC; + int depth, x, y, width, height; + int leftPad; + int format; + char *pImage; +{ + PixmapPtr pPixmap; + + if ((width == 0) || (height == 0)) + return; + + if (format != ZPixmap || depth == 1 || pDraw->depth == 1) { + pPixmap = GetScratchPixmapHeader(pDraw->pScreen, width+leftPad, height, + depth, depth, + BitmapBytePad(width+leftPad), + (pointer)pImage); + if (!pPixmap) + return; + + pGC->fExpose = FALSE; + if (format == XYBitmap) + (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, pDraw, pGC, leftPad, + 0, width, height, x, y, 1); + else { +#if 0 + /* XXX: bit plane order wronge ! */ + pPixmap->drawable.depth = 1; + pPixmap->drawable.bitsPerPixel = 1; + + switch (pGC->alu) { + case GXcopy: + doBitBlt = afbDoBitbltCopy; + break; + case GXxor: + doBitBlt = afbDoBitbltXor; + break; + case GXcopyInverted: + doBitBlt = afbDoBitbltCopyInverted; + break; + case GXor: + doBitBlt = afbDoBitbltOr; + break; + default: + doBitBlt = afbDoBitbltGeneral; + break; + } + + for (plane = (1L << (pPixmap->drawable.depth - 1)); plane; + plane >>= 1) { + (void)afbBitBlt((DrawablePtr)pPixmap, pDraw, pGC, leftPad, 0, + width, height, x, y, doBitBlt, plane); + /* pDraw->devKind += sizeDst; */ + } +#else + (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, pDraw, pGC, leftPad, + 0, width, height, x, y); +#endif + } + + pGC->fExpose = TRUE; + FreeScratchPixmapHeader(pPixmap); + } else { + /* Chunky to planar conversion required */ + + PixmapPtr pPixmap; + ScreenPtr pScreen = pDraw->pScreen; + int widthSrc; + int start_srcshift; + register int b; + register int dstshift; + register int shift_step; + register PixelType dst; + register PixelType srcbits; + register PixelType *pdst; + register PixelType *psrc; + int start_bit; + register int nl; + register int h; + register int d; + int sizeDst; + PixelType *pdstBase; + int widthDst; + int depthDst; + + /* Create a tmp pixmap */ + pPixmap = (pScreen->CreatePixmap)(pScreen, width, height, depth); + if (!pPixmap) + return; + + afbGetPixelWidthSizeDepthAndPointer((DrawablePtr)pPixmap, widthDst, + sizeDst, depthDst, pdstBase); + + widthSrc = PixmapWidthInPadUnits(width, depth); + /* XXX: if depth == 8, use fast chunky to planar assembly function.*/ + if (depth > 4) { + start_srcshift = 24; + shift_step = 8; + } else { + start_srcshift = 28; + shift_step = 4; + } + + for (d = 0; d < depth; d++, pdstBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + start_bit = start_srcshift + d; + psrc = (PixelType *)pImage; + pdst = pdstBase; + h = height; + + while (h--) { + dstshift = PPW - 1; + dst = 0; + nl = widthSrc; + while (nl--) { + srcbits = *psrc++; + for (b = start_bit; b >= 0; b -= shift_step) { + dst |= ((srcbits >> b) & 1) << dstshift; + if (--dstshift < 0) { + dstshift = PPW - 1; + *pdst++ = dst; + dst = 0; + } + } + } + if (dstshift != PPW - 1) + *pdst++ = dst; + } + } /* for (d = ...) */ + + pGC->fExpose = FALSE; + (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, pDraw, pGC, leftPad, 0, + width, height, x, y); + pGC->fExpose = TRUE; + (*pScreen->DestroyPixmap)(pPixmap); + } +} + +void +afbGetImage(pDrawable, sx, sy, width, height, format, planemask, pdstLine) + DrawablePtr pDrawable; + int sx, sy, width, height; + unsigned int format; + unsigned long planemask; + char *pdstLine; +{ + BoxRec box; + DDXPointRec ptSrc; + RegionRec rgnDst; + ScreenPtr pScreen; + PixmapPtr pPixmap; + + if ((width == 0) || (height == 0)) + return; + + pScreen = pDrawable->pScreen; + sx += pDrawable->x; + sy += pDrawable->y; + + if (format == XYPixmap || pDrawable->depth == 1) { + pPixmap = GetScratchPixmapHeader(pScreen, width, height, 1, 1, + BitmapBytePad(width), (pointer)pdstLine); + if (!pPixmap) + return; + + ptSrc.x = sx; + ptSrc.y = sy; + box.x1 = 0; + box.y1 = 0; + box.x2 = width; + box.y2 = height; + REGION_INIT(pScreen, &rgnDst, &box, 1); + + pPixmap->drawable.depth = 1; + pPixmap->drawable.bitsPerPixel = 1; + /* dix layer only ever calls GetImage with 1 bit set in planemask + * when format is XYPixmap. + */ + afbDoBitblt(pDrawable, (DrawablePtr)pPixmap, GXcopy, &rgnDst, &ptSrc, + planemask); + + FreeScratchPixmapHeader(pPixmap); + REGION_UNINIT(pScreen, &rgnDst); + } else { + /* Planar to chunky conversion required */ + + PixelType *psrcBits; + PixelType *psrcLine; + PixelType startmask, endmask; + int depthSrc; + int widthSrc; + int sizeSrc; + int sizeDst; + int widthDst; + register PixelType *psrc; + register PixelType *pdst; + register PixelType dst; + register PixelType srcbits; + register int d; + register int b; + register int dstshift; + register int shift_step; + register int start_endbit; + int start_startbit; + register int end_endbit = 0; + register int start_dstshift; + register int nl; + register int h; + int nlmiddle; + + widthDst = PixmapWidthInPadUnits(width, pDrawable->depth); + sizeDst = widthDst * height; + + /* Clear the dest image */ + bzero(pdstLine, sizeDst << 2); + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, widthSrc, sizeSrc, + depthSrc, psrcBits); + + psrcBits = afbScanline(psrcBits, sx, sy, widthSrc); + + start_startbit = PPW - 1 - (sx & PIM); + if ((sx & PIM) + width < PPW) { + maskpartialbits(sx, width, startmask); + nlmiddle = 0; + endmask = 0; + start_endbit = PPW - ((sx + width) & PIM); + } else { + maskbits(sx, width, startmask, endmask, nlmiddle); + start_endbit = 0; + end_endbit = PPW - ((sx + width) & PIM); + } + /* ZPixmap images have either 4 or 8 bits per pixel dependent on + * depth. + */ + if (depthSrc > 4) { + start_dstshift = 24; + shift_step = 8; + } else { + start_dstshift = 28; + shift_step = 4; + } +#define SHIFT_BITS(start_bit,end_bit) \ +for (b = (start_bit); b >= (end_bit); b--) { \ + dst |= ((srcbits >> b) & 1) << dstshift; \ + if ((dstshift -= shift_step) < 0) { \ + dstshift = start_dstshift + d; \ + *pdst++ = dst; \ + dst = *pdst; \ + } \ +} \ + + for (d = 0; d < depthSrc; d++, psrcBits += sizeSrc) { /* @@@ NEXT PLANE @@@ */ + psrcLine = psrcBits; + pdst = (PixelType *)pdstLine; + h = height; + + while (h--) { + psrc = psrcLine; + psrcLine += widthSrc; + dst = *pdst; + dstshift = start_dstshift + d; + + if (startmask) { + srcbits = *psrc++ & startmask; + SHIFT_BITS(start_startbit, start_endbit); + } + + nl = nlmiddle; + while (nl--) { + srcbits = *psrc++; + SHIFT_BITS(PPW - 1, 0); + } + if (endmask) { + srcbits = *psrc & endmask; + SHIFT_BITS(PPW - 1, end_endbit); + } + + if (dstshift != start_dstshift + d) + *pdst++ = dst; + } /* while (h--) */ + } /* for (d = ...) */ + } +} diff --git a/afb/afbimggblt.c b/afb/afbimggblt.c new file mode 100644 index 000000000..fbffb35dc --- /dev/null +++ b/afb/afbimggblt.c @@ -0,0 +1,466 @@ +/* $XFree86: xc/programs/Xserver/afb/afbimggblt.c,v 3.1 1998/03/20 21:04:55 hohndel Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbimggblt.c,v 5.17 94/04/17 20:28:25 dpw Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "afb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "maskbits.h" + +/* + we should eventually special-case fixed-width fonts for ImageText. + + this works for fonts with glyphs <= 32 bits wide. + + the clipping calculations are done for worst-case fonts. +we make no assumptions about the heights, widths, or bearings +of the glyphs. if we knew that the glyphs are all the same height, +we could clip the tops and bottoms per clipping box, rather +than per character per clipping box. if we knew that the glyphs' +left and right bearings were wlle-behaved, we could clip a single +character at the start, output until the last unclipped +character, and then clip the last one. this is all straightforward +to determine based on max-bounds and min-bounds from the font. + there is some inefficiency introduced in the per-character +clipping to make what's going on clearer. + + (it is possible, for example, for a font to be defined in which the +next-to-last character in a font would be clipped out, but the last +one wouldn't. the code below deals with this.) + + Image text looks at the bits in the glyph and the fg and bg in the +GC. it paints a rectangle, as defined in the protocol dcoument, +and the paints the characters. + + the register allocations for startmask and endmask may not +be the right thing. are there two other deserving candidates? +xoff, pdst, pglyph, and tmpSrc seem like the right things, though. +*/ + +void +afbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) + DrawablePtr pDrawable; + GC *pGC; + int x, y; + unsigned int nglyph; + CharInfoPtr *ppci; /* array of character info */ + pointer pglyphBase; /* start of array of glyphs */ +{ + ExtentInfoRec info; /* used by QueryGlyphExtents() */ + BoxRec bbox; /* string's bounding box */ + xRectangle backrect;/* backing rectangle to paint. + in the general case, NOT necessarily + the same as the string's bounding box + */ + + CharInfoPtr pci; + int xorg, yorg; /* origin of drawable in bitmap */ + int widthDst; /* width of dst in longwords */ + + /* these keep track of the character origin */ + PixelType *pdstBase; + /* points to longword with character origin */ + int xchar; /* xorigin of char (mod 32) */ + + /* these are used for placing the glyph */ + register int xoff; /* x offset of left edge of glyph (mod 32) */ + register PixelType *pdst; + /* pointer to current longword in dst */ + + register int d; + int depthDst; + int sizeDst; + int hSave; + int w; /* width of glyph in bits */ + int h; /* height of glyph */ + int widthGlyph; /* width of glyph, in bytes */ + unsigned char rrops[AFB_MAX_DEPTH]; + register unsigned char *pglyph; + /* pointer to current row of glyph */ + unsigned char *pglyphSave; + + /* used for putting down glyph */ + register PixelType tmpSrc; + /* for getting bits from glyph */ + register PixelType startmask; + register PixelType endmask; + + register int nFirst;/* bits of glyph in current longword */ + PixelType *pdstSave; + int oldFill; + afbPrivGC *pPriv = (afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr); + + xorg = pDrawable->x; + yorg = pDrawable->y; + afbGetPixelWidthSizeDepthAndPointer(pDrawable, widthDst, sizeDst, depthDst, + pdstBase); + + QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info); + + backrect.x = x; + backrect.y = y - FONTASCENT(pGC->font); + backrect.width = info.overallWidth; + backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); + + x += xorg; + y += yorg; + + bbox.x1 = x + info.overallLeft; + bbox.x2 = x + info.overallRight; + bbox.y1 = y - info.overallAscent; + bbox.y2 = y + info.overallDescent; + + oldFill = pGC->fillStyle; + pGC->fillStyle = FillSolid; + afbReduceRop (pGC->alu, pGC->bgPixel, pGC->planemask, pGC->depth, + pPriv->rrops); + afbPolyFillRect(pDrawable, pGC, 1, &backrect); + pGC->fillStyle = oldFill; + afbReduceRop (pGC->alu, pGC->fgPixel, pGC->planemask, pGC->depth, + pPriv->rrops); + afbReduceRop (GXcopy, pGC->fgPixel, pGC->planemask, pGC->depth, rrops); + + /* the faint-hearted can open their eyes now */ + + switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox)) { + case rgnOUT: + break; + case rgnIN: + pdstBase = afbScanlineNoBankSwitch(pdstBase, x, y, widthDst); + xchar = x & PIM; + + while(nglyph--) { + pci = *ppci; + pglyphSave = FONTGLYPHBITS(pglyphBase, pci); + w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing; + hSave = pci->metrics.ascent + pci->metrics.descent; + widthGlyph = GLYPHWIDTHBYTESPADDED(pci); + /* start at top scanline of glyph */ + pdstSave = afbScanlineDelta(pdstBase, -pci->metrics.ascent, + widthDst); + + /* find correct word in scanline and x offset within it + for left edge of glyph + */ + xoff = xchar + pci->metrics.leftSideBearing; + if (xoff > PLST) { + pdstSave++; + xoff &= PIM; + } else if (xoff < 0) { + xoff += PPW; + pdstSave--; + } + + for (d = 0; d < depthDst; d++) { + h = hSave; + pdst = pdstSave; + pdstSave += sizeDst; /* @@@ NEXT PLANE @@@ */ + pglyph = pglyphSave; + + if ((xoff + w) <= PPW) { + /* glyph all in one longword */ + maskpartialbits(xoff, w, startmask); + + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_WHITE: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst |= SCRRIGHT(tmpSrc, xoff) & startmask; + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_NOP: + break; + } + } else { + /* glyph crosses longword boundary */ + maskPPWbits(xoff, w, startmask, endmask); + nFirst = PPW - xoff; + + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask); + *(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_WHITE: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst |= SCRRIGHT(tmpSrc, xoff) & startmask; + *(pdst+1) |= SCRLEFT(tmpSrc, nFirst) & endmask; + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_NOP: + break; + } + } /* glyph crosses longwords boundary */ + } /* depth loop */ + /* update character origin */ + x += pci->metrics.characterWidth; + xchar += pci->metrics.characterWidth; + if (xchar > PLST) { + xchar -= PPW; + pdstBase++; + } else if (xchar < 0) { + xchar += PPW; + pdstBase--; + } + ppci++; + } /* while nglyph-- */ + break; + case rgnPART: + { + afbTEXTPOS *ppos; + int nbox; + BoxPtr pbox; + RegionPtr cclip; + int xpos; /* x position of char origin */ + int i; + BoxRec clip; + int leftEdge, rightEdge; + int topEdge, bottomEdge; + int glyphRow; /* first row of glyph not wholly + clipped out */ + int glyphCol; /* leftmost visible column of glyph */ + int getWidth; /* bits to get from glyph */ + + if(!(ppos = (afbTEXTPOS *)ALLOCATE_LOCAL(nglyph * sizeof(afbTEXTPOS)))) + return; + + pdstBase = afbScanlineNoBankSwitch(pdstBase, x, y, widthDst); + xpos = x; + xchar = xpos & PIM; + + for (i = 0; i < nglyph; i++) { + pci = ppci[i]; + + ppos[i].xpos = xpos; + ppos[i].xchar = xchar; + ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing; + ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing; + ppos[i].topEdge = y - pci->metrics.ascent; + ppos[i].bottomEdge = y + pci->metrics.descent; + ppos[i].pdstBase = pdstBase; + ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci); + + xpos += pci->metrics.characterWidth; + xchar += pci->metrics.characterWidth; + if (xchar > PLST) { + xchar &= PIM; + pdstBase++; + } else if (xchar < 0) { + xchar += PPW; + pdstBase--; + } + } + + cclip = pGC->pCompositeClip; + pbox = REGION_RECTS(cclip); + nbox = REGION_NUM_RECTS(cclip); + + /* HACK ALERT + since we continue out of the loop below so often, it + is easier to increment pbox at the top than at the end. + don't try this at home. + */ + pbox--; + while(nbox--) { + pbox++; + clip.x1 = max(bbox.x1, pbox->x1); + clip.y1 = max(bbox.y1, pbox->y1); + clip.x2 = min(bbox.x2, pbox->x2); + clip.y2 = min(bbox.y2, pbox->y2); + if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1)) + continue; + + for(i=0; i<nglyph; i++) { + pci = ppci[i]; + xchar = ppos[i].xchar; + + /* clip the left and right edges */ + if (ppos[i].leftEdge < clip.x1) + leftEdge = clip.x1; + else + leftEdge = ppos[i].leftEdge; + + if (ppos[i].rightEdge > clip.x2) + rightEdge = clip.x2; + else + rightEdge = ppos[i].rightEdge; + + w = rightEdge - leftEdge; + if (w <= 0) + continue; + + /* clip the top and bottom edges */ + if (ppos[i].topEdge < clip.y1) + topEdge = clip.y1; + else + topEdge = ppos[i].topEdge; + + if (ppos[i].bottomEdge > clip.y2) + bottomEdge = clip.y2; + else + bottomEdge = ppos[i].bottomEdge; + + hSave = bottomEdge - topEdge; + if (hSave <= 0) + continue; + + glyphRow = (topEdge - y) + pci->metrics.ascent; + widthGlyph = ppos[i].widthGlyph; + pglyphSave = FONTGLYPHBITS(pglyphBase, pci); + pglyphSave += (glyphRow * widthGlyph); + + glyphCol = (leftEdge - ppos[i].xpos) - + (pci->metrics.leftSideBearing); + getWidth = w + glyphCol; + + pdstSave = afbScanlineDelta(ppos[i].pdstBase, -(y-topEdge), + widthDst); + xoff = xchar + (leftEdge - ppos[i].xpos); + if (xoff > PLST) { + xoff &= PIM; + pdstSave++; + } else if (xoff < 0) { + xoff += PPW; + pdstSave--; + } + + for (d = 0; d < depthDst; d++) { + h = hSave; + pdst = pdstSave; + pdstSave += sizeDst; /* @@@ NEXT PLANE @@@ */ + pglyph = pglyphSave; + + if ((xoff + w) <= PPW) { + maskpartialbits(xoff, w, startmask); + + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_WHITE: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst |= SCRRIGHT(tmpSrc, xoff) & startmask; + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_NOP: + break; + } + } else { + maskPPWbits(xoff, w, startmask, endmask); + nFirst = PPW - xoff; + + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask); + *(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_WHITE: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst |= SCRRIGHT(tmpSrc, xoff) & startmask; + *(pdst+1) |= SCRLEFT(tmpSrc, nFirst) & endmask; + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_NOP: + break; + } + } + } /* depth */ + } /* for each glyph */ + } /* while nbox-- */ + DEALLOCATE_LOCAL(ppos); + break; + } + + default: + break; + } +} diff --git a/afb/afbline.c b/afb/afbline.c new file mode 100644 index 000000000..796ddffeb --- /dev/null +++ b/afb/afbline.c @@ -0,0 +1,702 @@ +/* $XFree86: xc/programs/Xserver/afb/afbline.c,v 3.2 2001/10/28 03:32:58 tsi Exp $ */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbline.c,v 5.18 94/04/17 20:28:26 dpw Exp $ */ + +#include "X.h" + +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "mistruct.h" + +#include "afb.h" +#include "maskbits.h" +#include "miline.h" + +/* single-pixel lines on a color frame buffer + + NON-SLOPED LINES + horizontal lines are always drawn left to right; we have to +move the endpoints right by one after they're swapped. + horizontal lines will be confined to a single band of a +region. the code finds that band (giving up if the lower +bound of the band is above the line we're drawing); then it +finds the first box in that band that contains part of the +line. we clip the line to subsequent boxes in that band. + vertical lines are always drawn top to bottom (y-increasing.) +this requires adding one to the y-coordinate of each endpoint +after swapping. + + SLOPED LINES + when clipping a sloped line, we bring the second point inside +the clipping box, rather than one beyond it, and then add 1 to +the length of the line before drawing it. this lets us use +the same box for finding the outcodes for both endpoints. since +the equation for clipping the second endpoint to an edge gives us +1 beyond the edge, we then have to move the point towards the +first point by one step on the major axis. + eventually, there will be a diagram here to explain what's going +on. the method uses Cohen-Sutherland outcodes to determine +outsideness, and a method similar to Pike's layers for doing the +actual clipping. + +*/ + +void +#ifdef POLYSEGMENT +afbSegmentSS(pDrawable, pGC, nseg, pSeg) + DrawablePtr pDrawable; + GCPtr pGC; + int nseg; + register xSegment *pSeg; +#else +afbLineSS(pDrawable, pGC, mode, npt, pptInit) + DrawablePtr pDrawable; + GCPtr pGC; + int mode; /* Origin or Previous */ + int npt; /* number of points */ + DDXPointPtr pptInit; +#endif +{ + int nboxInit; + register int nbox; + BoxPtr pboxInit; + register BoxPtr pbox; +#ifndef POLYSEGMENT + register DDXPointPtr ppt; /* pointer to list of translated points */ +#endif + + unsigned int oc1; /* outcode of point 1 */ + unsigned int oc2; /* outcode of point 2 */ + + PixelType *addrlBase; /* pointer to start of drawable */ + int nlwidth; /* width in longwords of destination pixmap */ + int xorg, yorg; /* origin of window */ + + int adx; /* abs values of dx and dy */ + int ady; + int signdx; /* sign of dx and dy */ + int signdy; + int e, e1, e2; /* bresenham error and increments */ + int len; /* length of segment */ + int axis; /* major axis */ + int octant; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + int depthDst; +#ifndef POLYSEGMENT + PixelType *addrl; /* address of destination pixmap */ + int d; +#endif + int sizeDst; + unsigned char *rrops; + + /* a bunch of temporaries */ + register int y1, y2; + register int x1, x2; + RegionPtr cclip; + + cclip = pGC->pCompositeClip; + rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops; + pboxInit = REGION_RECTS(cclip); + nboxInit = REGION_NUM_RECTS(cclip); + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + addrlBase); + + xorg = pDrawable->x; + yorg = pDrawable->y; +#ifdef POLYSEGMENT + while (nseg--) +#else + ppt = pptInit; + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; + while(--npt) +#endif + { + nbox = nboxInit; + pbox = pboxInit; + +#ifdef POLYSEGMENT + x1 = pSeg->x1 + xorg; + y1 = pSeg->y1 + yorg; + x2 = pSeg->x2 + xorg; + y2 = pSeg->y2 + yorg; + pSeg++; +#else + x1 = x2; + y1 = y2; + ++ppt; + if (mode == CoordModePrevious) { + xorg = x1; + yorg = y1; + } + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; +#endif + + if (x1 == x2) /* vertical line */ + { + /* make the line go top to bottom of screen, keeping + endpoint semantics + */ + if (y1 > y2) { + register int tmp; + + tmp = y2; + y2 = y1 + 1; + y1 = tmp + 1; +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) + y1--; +#endif + } +#ifdef POLYSEGMENT + else if (pGC->capStyle != CapNotLast) + y2++; +#endif + /* get to first band that might contain part of line */ + while ((nbox) && (pbox->y2 <= y1)) { + pbox++; + nbox--; + } + + if (nbox) { + /* stop when lower edge of box is beyond end of line */ + while((nbox) && (y2 >= pbox->y1)) { + if ((x1 >= pbox->x1) && (x1 < pbox->x2)) { + int y1t, y2t; + /* this box has part of the line in it */ + y1t = max(y1, pbox->y1); + y2t = min(y2, pbox->y2); + if (y1t != y2t) + afbVertS(addrlBase, nlwidth, sizeDst, depthDst, x1, y1t, + y2t-y1t, rrops); /* @@@ NEXT PLANE PASSED @@@ */ + } + nbox--; + pbox++; + } + } +#ifndef POLYSEGMENT + y2 = ppt->y + yorg; +#endif + } else if (y1 == y2) /* horizontal line */ { + /* force line from left to right, keeping + endpoint semantics + */ + if (x1 > x2) { + register int tmp; + + tmp = x2; + x2 = x1 + 1; + x1 = tmp + 1; +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) + x1--; +#endif + } +#ifdef POLYSEGMENT + else if (pGC->capStyle != CapNotLast) + x2++; +#endif + + /* find the correct band */ + while( (nbox) && (pbox->y2 <= y1)) { + pbox++; + nbox--; + } + + /* try to draw the line, if we haven't gone beyond it */ + if ((nbox) && (pbox->y1 <= y1)) { + int tmp; + + /* when we leave this band, we're done */ + tmp = pbox->y1; + while((nbox) && (pbox->y1 == tmp)) { + int x1t, x2t; + + if (pbox->x2 <= x1) { + /* skip boxes until one might contain start point */ + nbox--; + pbox++; + continue; + } + + /* stop if left of box is beyond right of line */ + if (pbox->x1 >= x2) { + nbox = 0; + break; + } + + x1t = max(x1, pbox->x1); + x2t = min(x2, pbox->x2); + if (x1t != x2t) + afbHorzS(addrlBase, nlwidth, sizeDst, depthDst, x1t, y1, + x2t-x1t, rrops); /* @@@ NEXT PLANE PASSED @@@ */ + nbox--; + pbox++; + } + } +#ifndef POLYSEGMENT + x2 = ppt->x + xorg; +#endif + } + else /* sloped line */ + { + CalcLineDeltas(x1, y1, x2, y2, adx, ady, + signdx, signdy, 1, 1, octant); + + if (adx > ady) { + axis = X_AXIS; + e1 = ady << 1; + e2 = e1 - (adx << 1); + e = e1 - adx; + } else { + axis = Y_AXIS; + e1 = adx << 1; + e2 = e1 - (ady << 1); + e = e1 - ady; + SetYMajorOctant(octant); + } + + FIXUP_ERROR(e, octant, bias); + + /* we have bresenham parameters and two points. + all we have to do now is clip and draw. + */ + + while(nbox--) { + oc1 = 0; + oc2 = 0; + OUTCODES(oc1, x1, y1, pbox); + OUTCODES(oc2, x2, y2, pbox); + if ((oc1 | oc2) == 0) { + if (axis == X_AXIS) + len = adx; + else + len = ady; +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) + len++; +#endif + afbBresS(addrlBase, nlwidth, sizeDst, depthDst, signdx, signdy, + axis, x1, y1, e, e1, e2, len, rrops); /* @@@ NEXT PLANE PASSED @@@ */ + break; + } else if (oc1 & oc2) { + pbox++; + } else { + int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; + int clip1 = 0, clip2 = 0; + int clipdx, clipdy; + int err; + + if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, + pbox->y2-1, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, &clip1, &clip2, + octant, bias, oc1, oc2) == -1) { + pbox++; + continue; + } + + if (axis == X_AXIS) + len = abs(new_x2 - new_x1); + else + len = abs(new_y2 - new_y1); +#ifdef POLYSEGMENT + if (clip2 != 0 || pGC->capStyle != CapNotLast) + len++; +#else + len += (clip2 != 0); +#endif + if (len) { + /* unwind bresenham error term to first point */ + if (clip1) { + clipdx = abs(new_x1 - x1); + clipdy = abs(new_y1 - y1); + if (axis == X_AXIS) + err = e+((clipdy*e2) + ((clipdx-clipdy)*e1)); + else + err = e+((clipdx*e2) + ((clipdy-clipdx)*e1)); + } + else + err = e; + afbBresS(addrlBase, nlwidth, sizeDst, depthDst, signdx, + signdy, axis, new_x1, new_y1, err, e1, e2, len, + rrops); /* @@@ NEXT PLANE PASSED @@@ */ + } + pbox++; + } + } /* while (nbox--) */ + } /* sloped line */ + } /* while (nline--) */ + +#ifndef POLYSEGMENT + + /* paint the last point if the end style isn't CapNotLast. + (Assume that a projecting, butt, or round cap that is one + pixel wide is the same as the single pixel of the endpoint.) + */ + + if ((pGC->capStyle != CapNotLast) && + ((ppt->x + xorg != pptInit->x + pDrawable->x) || + (ppt->y + yorg != pptInit->y + pDrawable->y) || + (ppt == pptInit + 1))) { + nbox = nboxInit; + pbox = pboxInit; + while (nbox--) { + if ((x2 >= pbox->x1) && (y2 >= pbox->y1) && (x2 < pbox->x2) && + (y2 < pbox->y2)) { + for (d = 0; d < depthDst; d++) { + addrl = afbScanline(addrlBase, x2, y2, nlwidth); + addrlBase += sizeDst; /* @@@ NEXT PLANE @@@ */ + + switch(rrops[d]) { + case RROP_BLACK: + *addrl &= rmask[x2 & PIM]; + break; + case RROP_WHITE: + *addrl |= mask[x2 & PIM]; + break; + case RROP_INVERT: + *addrl ^= mask[x2 & PIM]; + break; + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ...) */ + break; + } else + pbox++; + } + } +#endif +} + +/* + * Draw dashed 1-pixel lines. + */ + +void +#ifdef POLYSEGMENT +afbSegmentSD(pDrawable, pGC, nseg, pSeg) + DrawablePtr pDrawable; + register GCPtr pGC; + int nseg; + register xSegment *pSeg; +#else +afbLineSD(pDrawable, pGC, mode, npt, pptInit) + DrawablePtr pDrawable; + register GCPtr pGC; + int mode; /* Origin or Previous */ + int npt; /* number of points */ + DDXPointPtr pptInit; +#endif +{ + int nboxInit; + register int nbox; + BoxPtr pboxInit; + register BoxPtr pbox; +#ifndef POLYSEGMENT + register DDXPointPtr ppt; /* pointer to list of translated points */ +#endif + + register unsigned int oc1; /* outcode of point 1 */ + register unsigned int oc2; /* outcode of point 2 */ + + PixelType *addrlBase; /* address of destination pixmap */ + int nlwidth; /* width in longwords of destination pixmap */ + int sizeDst; + int depthDst; + int xorg, yorg; /* origin of window */ + + int adx; /* abs values of dx and dy */ + int ady; + int signdx; /* sign of dx and dy */ + int signdy; + int e, e1, e2; /* bresenham error and increments */ + int len; /* length of segment */ + int axis; /* major axis */ + int octant; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + int x1, x2, y1, y2; + RegionPtr cclip; + unsigned char *rrops; + unsigned char bgrrops[AFB_MAX_DEPTH]; + unsigned char *pDash; + int dashOffset; + int numInDashList; + int dashIndex; + int isDoubleDash; + int dashIndexTmp, dashOffsetTmp; + int unclippedlen; +#ifndef POLYSEGMENT + PixelType *addrl; + int d; +#endif + + cclip = pGC->pCompositeClip; + rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops; + pboxInit = REGION_RECTS(cclip); + nboxInit = REGION_NUM_RECTS(cclip); + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + addrlBase); + + /* compute initial dash values */ + + pDash = (unsigned char *) pGC->dash; + numInDashList = pGC->numInDashList; + isDoubleDash = (pGC->lineStyle == LineDoubleDash); + dashIndex = 0; + dashOffset = 0; + miStepDash ((int)pGC->dashOffset, &dashIndex, pDash, + numInDashList, &dashOffset); + + if (isDoubleDash) + afbReduceRop (pGC->alu, pGC->bgPixel, pGC->planemask, pGC->depth, + bgrrops); + + xorg = pDrawable->x; + yorg = pDrawable->y; +#ifdef POLYSEGMENT + while (nseg--) +#else + ppt = pptInit; + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; + while(--npt) +#endif + { + nbox = nboxInit; + pbox = pboxInit; + +#ifdef POLYSEGMENT + x1 = pSeg->x1 + xorg; + y1 = pSeg->y1 + yorg; + x2 = pSeg->x2 + xorg; + y2 = pSeg->y2 + yorg; + pSeg++; +#else + x1 = x2; + y1 = y2; + ++ppt; + if (mode == CoordModePrevious) { + xorg = x1; + yorg = y1; + } + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; +#endif + + CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, + 1, 1, octant); + + if (adx > ady) { + axis = X_AXIS; + e1 = ady << 1; + e2 = e1 - (adx << 1); + e = e1 - adx; + unclippedlen = adx; + } else { + axis = Y_AXIS; + e1 = adx << 1; + e2 = e1 - (ady << 1); + e = e1 - ady; + unclippedlen = ady; + SetYMajorOctant(octant); + } + + FIXUP_ERROR(e, octant, bias); + + /* we have bresenham parameters and two points. + all we have to do now is clip and draw. + */ + + while(nbox--) { + oc1 = 0; + oc2 = 0; + OUTCODES(oc1, x1, y1, pbox); + OUTCODES(oc2, x2, y2, pbox); + if ((oc1 | oc2) == 0) { +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) + unclippedlen++; + dashIndexTmp = dashIndex; + dashOffsetTmp = dashOffset; + afbBresD(&dashIndexTmp, pDash, numInDashList, &dashOffsetTmp, + isDoubleDash, addrlBase, nlwidth, sizeDst, depthDst, + signdx, signdy, axis, x1, y1, e, e1, e2, unclippedlen, + rrops, bgrrops); /* @@@ NEXT PLANE PASSED @@@ */ + break; +#else + afbBresD(&dashIndex, pDash, numInDashList, &dashOffset, + isDoubleDash, addrlBase, nlwidth, sizeDst, depthDst, + signdx, signdy, axis, x1, y1, e, e1, e2, unclippedlen, + rrops, bgrrops); /* @@@ NEXT PLANE PASSED @@@ */ + goto dontStep; +#endif + } else if (oc1 & oc2) { + pbox++; + } else /* have to clip */ { + int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; + int clip1 = 0, clip2 = 0; + int clipdx, clipdy; + int err; + + if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, pbox->y2-1, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, &clip1, &clip2, + octant, bias, oc1, oc2) == -1) { + pbox++; + continue; + } + dashIndexTmp = dashIndex; + dashOffsetTmp = dashOffset; + if (clip1) { + int dlen; + + if (axis == X_AXIS) + dlen = abs(new_x1 - x1); + else + dlen = abs(new_y1 - y1); + miStepDash (dlen, &dashIndexTmp, pDash, + numInDashList, &dashOffsetTmp); + } + if (axis == X_AXIS) + len = abs(new_x2 - new_x1); + else + len = abs(new_y2 - new_y1); +#ifdef POLYSEGMENT + if (clip2 != 0 || pGC->capStyle != CapNotLast) + len++; +#else + len += (clip2 != 0); +#endif + if (len) { + /* unwind bresenham error term to first point */ + if (clip1) { + clipdx = abs(new_x1 - x1); + clipdy = abs(new_y1 - y1); + if (axis == X_AXIS) + err = e+((clipdy*e2) + ((clipdx-clipdy)*e1)); + else + err = e+((clipdx*e2) + ((clipdy-clipdx)*e1)); + } + else + err = e; + afbBresD(&dashIndexTmp, pDash, numInDashList, &dashOffsetTmp, + isDoubleDash, addrlBase, nlwidth, sizeDst, depthDst, + signdx, signdy, axis, new_x1, new_y1, err, e1, e2, + len, rrops, bgrrops); /* @@@ NEXT PLANE PASSED @@@ */ + } + pbox++; + } + } /* while (nbox--) */ +#ifndef POLYSEGMENT + /* + * walk the dash list around to the next line + */ + miStepDash (unclippedlen, &dashIndex, pDash, + numInDashList, &dashOffset); +dontStep: ; +#endif + } /* while (nline--) */ + +#ifndef POLYSEGMENT + /* paint the last point if the end style isn't CapNotLast. + (Assume that a projecting, butt, or round cap that is one + pixel wide is the same as the single pixel of the endpoint.) + */ + + if ((pGC->capStyle != CapNotLast) && + ((dashIndex & 1) == 0 || isDoubleDash) && + ((ppt->x + xorg != pptInit->x + pDrawable->x) || + (ppt->y + yorg != pptInit->y + pDrawable->y) || + (ppt == pptInit + 1))) { + nbox = nboxInit; + pbox = pboxInit; + while (nbox--) { + if ((x2 >= pbox->x1) && (y2 >= pbox->y1) && (x2 < pbox->x2) && + (y2 < pbox->y2)) { + int rop; + + for (d = 0; d < depthDst; d++) { + addrl = afbScanline(addrlBase, x2, y2, nlwidth); + addrlBase += sizeDst; /* @@@ NEXT PLANE @@@ */ + + rop = rrops[d]; + if (dashIndex & 1) + rop = bgrrops[d]; + + switch (rop) { + case RROP_BLACK: + *addrl &= rmask[x2 & PIM]; + break; + case RROP_WHITE: + *addrl |= mask[x2 & PIM]; + break; + + case RROP_INVERT: + *addrl ^= mask[x2 & PIM]; + break; + + case RROP_NOP: + break; + } + } /* for (d = ...) */ + break; + } else + pbox++; + } + } +#endif +} diff --git a/afb/afbmisc.c b/afb/afbmisc.c new file mode 100644 index 000000000..c0ae1c545 --- /dev/null +++ b/afb/afbmisc.c @@ -0,0 +1,92 @@ +/* $XFree86: xc/programs/Xserver/afb/afbmisc.c,v 3.0 1996/08/18 01:45:44 dawes Exp $ */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbmisc.c,v 5.4 94/04/17 20:28:27 dpw Exp $ */ + +#include "X.h" +#include "misc.h" +#include "cursor.h" +#include "scrnintstr.h" + +#include "afb.h" + +/*ARGSUSED*/ +void +afbQueryBestSize(class, pwidth, pheight, pScreen) +int class; +unsigned short *pwidth; +unsigned short *pheight; +ScreenPtr pScreen; +{ + unsigned width, test; + + switch(class) { + case CursorShape: + if (*pwidth > pScreen->width) + *pwidth = pScreen->width; + if (*pheight > pScreen->height) + *pheight = pScreen->height; + break; + case TileShape: + case StippleShape: + width = *pwidth; + if (!width) break; + /* Return the closes power of two not less than what they gave me */ + test = 0x80000000; + /* Find the highest 1 bit in the width given */ + while(!(test & width)) + test >>= 1; + /* If their number is greater than that, bump up to the next + * power of two */ + if((test - 1) & width) + test <<= 1; + *pwidth = test; + /* We don't care what height they use */ + break; + } +} diff --git a/afb/afbpixmap.c b/afb/afbpixmap.c new file mode 100644 index 000000000..fe0d8bc79 --- /dev/null +++ b/afb/afbpixmap.c @@ -0,0 +1,292 @@ +/* $XFree86: xc/programs/Xserver/afb/afbpixmap.c,v 3.1 1997/06/03 14:11:07 hohndel Exp $ */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbpixmap.c,v 5.13 94/04/17 20:28:28 dpw Exp $ */ + +/* pixmap management + written by drewry, september 1986 + + on a monchrome device, a pixmap is a bitmap. +*/ + +#include "Xmd.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "maskbits.h" + +#include "afb.h" +#include "mi.h" + +#include "servermd.h" +#include "mfb.h" + +PixmapPtr +afbCreatePixmap(pScreen, width, height, depth) + ScreenPtr pScreen; + int width; + int height; + int depth; +{ + PixmapPtr pPixmap; + int datasize; + int paddedWidth; + + paddedWidth = BitmapBytePad(width); + datasize = height * paddedWidth * depth; + pPixmap = AllocatePixmap(pScreen, datasize); + if (!pPixmap) + return(NullPixmap); + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = 0; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = depth; + pPixmap->drawable.id = 0; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->devKind = paddedWidth; + pPixmap->refcnt = 1; +#ifdef PIXPRIV + pPixmap->devPrivate.ptr = datasize ? + (pointer)((char *)pPixmap + pScreen->totalPixmapSize) : NULL; +#else + pPixmap->devPrivate.ptr = (pointer)(pPixmap + 1); +#endif + return(pPixmap); +} + +Bool +afbDestroyPixmap(pPixmap) + PixmapPtr pPixmap; +{ + if(--pPixmap->refcnt) + return(TRUE); + xfree(pPixmap); + return(TRUE); +} + + +PixmapPtr +afbCopyPixmap(pSrc) + register PixmapPtr pSrc; +{ + register PixmapPtr pDst; + int size; + ScreenPtr pScreen; + + size = pSrc->drawable.height * pSrc->devKind * pSrc->drawable.depth; + pScreen = pSrc->drawable.pScreen; + pDst = (*pScreen->CreatePixmap)(pScreen, pSrc->drawable.width, + pSrc->drawable.height, pSrc->drawable.depth); + if (!pDst) + return(NullPixmap); + memmove((char *)pDst->devPrivate.ptr, (char *)pSrc->devPrivate.ptr, size); + return(pDst); +} + + +/* replicates a pattern to be a full 32 bits wide. + relies on the fact that each scnaline is longword padded. + doesn't do anything if pixmap is not a factor of 32 wide. + changes width field of pixmap if successful, so that the fast + XRotatePixmap code gets used if we rotate the pixmap later. + + calculate number of times to repeat + for each scanline of pattern + zero out area to be filled with replicate + left shift and or in original as many times as needed +*/ +void +afbPadPixmap(pPixmap) + PixmapPtr pPixmap; +{ + register int width = pPixmap->drawable.width; + register int h; + register PixelType mask; + register PixelType *p; + register PixelType bits; /* real pattern bits */ + register int i; + int d; + int rep; /* repeat count for pattern */ + + if (width >= PPW) + return; + + rep = PPW/width; + if (rep*width != PPW) + return; + + mask = endtab[width]; + + p = (PixelType *)(pPixmap->devPrivate.ptr); + + for (d = 0; d < pPixmap->drawable.depth; d++) { + for (h = 0; h < pPixmap->drawable.height; h++) { + *p &= mask; + bits = *p; + for(i = 1; i < rep; i++) { + bits = SCRRIGHT(bits, width); + *p |= bits; + } + p++; /* @@@ NEXT PLANE @@@ */ + } + } + pPixmap->drawable.width = PPW; +} + +/* Rotates pixmap pPix by w pixels to the right on the screen. Assumes that + * words are PPW bits wide, and that the least significant bit appears on the + * left. + */ +void +afbXRotatePixmap(pPix, rw) + PixmapPtr pPix; + register int rw; +{ + register PixelType *pw, *pwFinal; + register PixelType t; + + if (pPix == NullPixmap) + return; + + pw = (PixelType *)pPix->devPrivate.ptr; + rw %= (int)pPix->drawable.width; + if (rw < 0) + rw += (int)pPix->drawable.width; + if(pPix->drawable.width == PPW) { + pwFinal = pw + pPix->drawable.height * pPix->drawable.depth; + while(pw < pwFinal) { + t = *pw; + *pw++ = SCRRIGHT(t, rw) | + (SCRLEFT(t, (PPW-rw)) & endtab[rw]); + } + } else { + /* We no longer do this. Validate doesn't try to rotate odd-size + * tiles or stipples. afbUnnatural<tile/stipple>FS works directly off + * the unrotate tile/stipple in the GC + */ + ErrorF("X internal error: trying to rotate odd-sized pixmap.\n"); + } + +} + +/* Rotates pixmap pPix by h lines. Assumes that h is always less than + pPix->height + works on any width. + */ +void +afbYRotatePixmap(pPix, rh) + register PixmapPtr pPix; + int rh; +{ + int nbyDown; /* bytes to move down to row 0; also offset of + row rh */ + int nbyUp; /* bytes to move up to line rh; also + offset of first line moved down to 0 */ + char *pbase; + char *ptmp; + int height; + int d; + + if (pPix == NullPixmap) + return; + height = (int) pPix->drawable.height; + rh %= height; + if (rh < 0) + rh += height; + + nbyDown = rh * pPix->devKind; + nbyUp = (pPix->devKind * height) - nbyDown; + + if(!(ptmp = (char *)ALLOCATE_LOCAL(nbyUp))) + return; + + for (d = 0; d < pPix->drawable.depth; d++) { + pbase = (char *)pPix->devPrivate.ptr + pPix->devKind * height * d; /* @@@ NEXT PLANE @@@ */ + + memmove(ptmp, pbase, nbyUp); /* save the low rows */ + memmove(pbase, pbase+nbyUp, nbyDown); /* slide the top rows down */ + memmove(pbase+nbyDown, ptmp, nbyUp); /* move lower rows up to row rh */ + } + DEALLOCATE_LOCAL(ptmp); +} + +void +afbCopyRotatePixmap(psrcPix, ppdstPix, xrot, yrot) + register PixmapPtr psrcPix, *ppdstPix; + int xrot, yrot; +{ + register PixmapPtr pdstPix; + + if ((pdstPix = *ppdstPix) && + (pdstPix->devKind == psrcPix->devKind) && + (pdstPix->drawable.height == psrcPix->drawable.height) && + (pdstPix->drawable.depth == psrcPix->drawable.depth)) { + memmove((char *)pdstPix->devPrivate.ptr, + (char *)psrcPix->devPrivate.ptr, + psrcPix->drawable.height * psrcPix->devKind * + psrcPix->drawable.depth); + pdstPix->drawable.width = psrcPix->drawable.width; + pdstPix->drawable.serialNumber = NEXT_SERIAL_NUMBER; + } else { + if (pdstPix) + /* FIX XBUG 6168 */ + (*pdstPix->drawable.pScreen->DestroyPixmap)(pdstPix); + *ppdstPix = pdstPix = afbCopyPixmap(psrcPix); + if (!pdstPix) + return; + } + afbPadPixmap(pdstPix); + if (xrot) + afbXRotatePixmap(pdstPix, xrot); + if (yrot) + afbYRotatePixmap(pdstPix, yrot); +} diff --git a/afb/afbply1rct.c b/afb/afbply1rct.c new file mode 100644 index 000000000..c0c2065f1 --- /dev/null +++ b/afb/afbply1rct.c @@ -0,0 +1,296 @@ +/* $XFree86: xc/programs/Xserver/afb/afbply1rct.c,v 3.2 2001/10/28 03:32:58 tsi Exp $ */ +/* + * $XConsortium: afbply1rct.c,v 1.9 94/04/17 20:28:28 dpw Exp $ + * +Copyright (c) 1990 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + * + * Author: Keith Packard, MIT X Consortium + */ + +#include "X.h" + +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "mistruct.h" + +#include "afb.h" +#include "maskbits.h" + +#if defined(mips) || defined(sparc) +#define GetHighWord(x) (((int)(x)) >> 16) +#else +#define GetHighWord(x) (((int)(x)) / 65536) +#endif + +#if IMAGE_BYTE_ORDER == MSBFirst +#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int)((short) (i)))) +#define coordToInt(x,y) (((x) << 16) | (y)) +#define intToX(i) (GetHighWord(i)) +#define intToY(i) ((int)((short) i)) +#else +#define intToCoord(i,x,y) (((x) = (int)((short) (i))), ((y) = GetHighWord(i))) +#define coordToInt(x,y) (((y) << 16) | (x)) +#define intToX(i) ((int)((short) (i))) +#define intToY(i) (GetHighWord(i)) +#endif + +void +afbFillPolygonSolid (pDrawable, pGC, shape, mode, count, ptsIn) + DrawablePtr pDrawable; + GCPtr pGC; + int shape; + int mode; + int count; + DDXPointPtr ptsIn; +{ + afbPrivGCPtr devPriv; + int nlwidth; + PixelType *addrl, *addr; + int maxy; + int origin; + register int vertex1, vertex2; + int c; + BoxPtr extents; + int clip; + int y; + int *vertex1p = NULL, *vertex2p; + int *endp; + int x1 = 0, x2 = 0; + int dx1 = 0, dx2 = 0; + int dy1 = 0, dy2 = 0; + int e1 = 0, e2 = 0; + int step1 = 0, step2 = 0; + int sign1 = 0, sign2 = 0; + int h; + int l, r; + PixelType mask, bits = ~((PixelType)0); + int nmiddle; + register unsigned char *rrops; + register int n; + register int d; + int sizeDst; + int depthDst; + register PixelType *pdst; + + devPriv = (afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr); + + if (mode == CoordModePrevious || shape != Convex || + REGION_NUM_RECTS(pGC->pCompositeClip) != 1) { + miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn); + return; + } + origin = *((int *) &pDrawable->x); + origin -= (origin & 0x8000) << 1; + extents = &pGC->pCompositeClip->extents; + vertex1 = *((int *) &extents->x1) - origin; + vertex2 = *((int *) &extents->x2) - origin - 0x00010001; + clip = 0; + y = 32767; + maxy = 0; + vertex2p = (int *) ptsIn; + endp = vertex2p + count; + while (count--) { + c = *vertex2p; + clip |= (c - vertex1) | (vertex2 - c); + c = intToY(c); + if (c < y) { + y = c; + vertex1p = vertex2p; + } + vertex2p++; + if (c > maxy) + maxy = c; + } + if (y == maxy) + return; + + if (clip & 0x80008000) { + miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn); + return; + } + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + addrl); + rrops = devPriv->rrops; + addrl = afbScanlineDelta(addrl, y + pDrawable->y, nlwidth); + origin = intToX(origin); + vertex2p = vertex1p; + vertex2 = vertex1 = *vertex2p++; + if (vertex2p == endp) + vertex2p = (int *) ptsIn; +#define Setup(c,x,vertex,dx,dy,e,sign,step) {\ + x = intToX(vertex); \ + if ((dy = intToY(c) - y)) { \ + dx = intToX(c) - x; \ + step = 0; \ + if (dx >= 0) { \ + e = 0; \ + sign = 1; \ + if (dx >= dy) {\ + step = dx / dy; \ + dx = dx % dy; \ + } \ + } else { \ + e = 1 - dy; \ + sign = -1; \ + dx = -dx; \ + if (dx >= dy) { \ + step = - (dx / dy); \ + dx = dx % dy; \ + } \ + } \ + } \ + x += origin; \ + vertex = c; \ +} + +#define Step(x,dx,dy,e,sign,step) {\ + x += step; \ + if ((e += dx) > 0) { \ + x += sign; \ + e -= dy; \ + } \ +} + for (;;) { + if (y == intToY(vertex1)) { + do { + if (vertex1p == (int *) ptsIn) + vertex1p = endp; + c = *--vertex1p; + Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1) + } while (y >= intToY(vertex1)); + h = dy1; + } else { + Step(x1,dx1,dy1,e1,sign1,step1) + h = intToY(vertex1) - y; + } + if (y == intToY(vertex2)) { + do { + c = *vertex2p++; + if (vertex2p == endp) + vertex2p = (int *) ptsIn; + Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2) + } while (y >= intToY(vertex2)); + if (dy2 < h) + h = dy2; + } else { + Step(x2,dx2,dy2,e2,sign2,step2) + if ((c = (intToY(vertex2) - y)) < h) + h = c; + } + /* fill spans for this segment */ + y += h; + for (;;) { + l = x1; + r = x2; + nmiddle = x2 - x1; + if (nmiddle < 0) { + nmiddle = -nmiddle; + l = x2; + r = x1; + } + c = l & PIM; + l -= c; + l = l >> PWSH; + addr = addrl + l; + if (c + nmiddle < PPW) { + mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle); + for (pdst = addr, d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */ + switch (rrops[d]) { + case RROP_BLACK: + *pdst &= ~mask; + break; + case RROP_WHITE: + *pdst |= mask; + break; + case RROP_INVERT: + *pdst ^= mask; + break; + case RROP_NOP: + break; + } + } + } else { + if (c) { + mask = SCRRIGHT(bits, c); + for (pdst = addr, d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */ + switch (rrops[d]) { + case RROP_BLACK: + *pdst &= ~mask; + break; + case RROP_WHITE: + *pdst |= mask; + break; + case RROP_INVERT: + *pdst ^= mask; + break; + case RROP_NOP: + break; + } + } + nmiddle += c - PPW; + addr++; + } + nmiddle >>= PWSH; + mask = ~SCRRIGHT(bits, r & PIM); + + for (d = 0; d < depthDst; d++, addr += sizeDst) { /* @@@ NEXT PLANE @@@ */ + n = nmiddle; + pdst = addr; + + switch (rrops[d]) { + case RROP_BLACK: + Duff (n, *pdst++ = 0;) + if (mask) + *pdst &= ~mask; + break; + case RROP_WHITE: + Duff (n, *pdst++ = ~0;); + if (mask) + *pdst |= mask; + break; + case RROP_INVERT: + Duff (n, *pdst++ ^= ~0;); + if (mask) + *pdst ^= mask; + break; + case RROP_NOP: + break; + } + } + } + if (!--h) + break; + afbScanlineInc(addrl, nlwidth); + Step(x1,dx1,dy1,e1,sign1,step1) + Step(x2,dx2,dy2,e2,sign2,step2) + } + if (y == maxy) + break; + afbScanlineInc(addrl, nlwidth); + } +} diff --git a/afb/afbplygblt.c b/afb/afbplygblt.c new file mode 100644 index 000000000..65cfcd1b0 --- /dev/null +++ b/afb/afbplygblt.c @@ -0,0 +1,457 @@ +/* $XFree86: xc/programs/Xserver/afb/afbplygblt.c,v 3.2 2001/10/28 03:32:58 tsi Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbimggblt.c,v 5.17 94/04/17 20:28:25 dpw Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "afb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "maskbits.h" + +/* + this works for fonts with glyphs <= 32 bits wide. + + the clipping calculations are done for worst-case fonts. +we make no assumptions about the heights, widths, or bearings +of the glyphs. if we knew that the glyphs are all the same height, +we could clip the tops and bottoms per clipping box, rather +than per character per clipping box. if we knew that the glyphs' +left and right bearings were wlle-behaved, we could clip a single +character at the start, output until the last unclipped +character, and then clip the last one. this is all straightforward +to determine based on max-bounds and min-bounds from the font. + there is some inefficiency introduced in the per-character +clipping to make what's going on clearer. + + (it is possible, for example, for a font to be defined in which the +next-to-last character in a font would be clipped out, but the last +one wouldn't. the code below deals with this.) + +*/ + +void +afbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) + DrawablePtr pDrawable; + GC *pGC; + int x, y; + unsigned int nglyph; + CharInfoPtr *ppci; /* array of character info */ + pointer pglyphBase; /* start of array of glyphs */ +{ + ExtentInfoRec info; /* used by QueryGlyphExtents() */ + BoxRec bbox; /* string's bounding box */ + + CharInfoPtr pci; + int xorg, yorg; /* origin of drawable in bitmap */ + int widthDst; /* width of dst in longwords */ + + /* these keep track of the character origin */ + PixelType *pdstBase; + /* points to longword with character origin */ + int xchar; /* xorigin of char (mod 32) */ + + /* these are used for placing the glyph */ + register int xoff; /* x offset of left edge of glyph (mod 32) */ + register PixelType *pdst; /* pointer to current longword in dst */ + + register int d; + int depthDst; + int sizeDst; + int hSave; + int w; /* width of glyph in bits */ + int h; /* height of glyph */ + int widthGlyph; /* width of glyph, in bytes */ + unsigned char *rrops; + register unsigned char *pglyph; + /* pointer to current row of glyph */ + unsigned char *pglyphSave; + + /* used for putting down glyph */ + register PixelType tmpSrc; + /* for getting bits from glyph */ + register PixelType startmask; + register PixelType endmask; + + register int nFirst; /* bits of glyph in current longword */ + PixelType *pdstSave; + + xorg = pDrawable->x; + yorg = pDrawable->y; + afbGetPixelWidthSizeDepthAndPointer(pDrawable, widthDst, sizeDst, depthDst, + pdstBase); + + QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info); + + x += xorg; + y += yorg; + + bbox.x1 = x + info.overallLeft; + bbox.x2 = x + info.overallRight; + bbox.y1 = y - info.overallAscent; + bbox.y2 = y + info.overallDescent; + + rrops = ((afbPrivGCPtr) pGC->devPrivates[afbGCPrivateIndex].ptr)->rrops; + + switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox)) { + case rgnOUT: + break; + case rgnIN: + pdstBase = afbScanlineNoBankSwitch(pdstBase, x, y, widthDst); + xchar = x & PIM; + + while(nglyph--) { + pci = *ppci; + pglyphSave = FONTGLYPHBITS(pglyphBase, pci); + w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing; + hSave = pci->metrics.ascent + pci->metrics.descent; + widthGlyph = GLYPHWIDTHBYTESPADDED(pci); + /* start at top scanline of glyph */ + pdstSave = afbScanlineDelta(pdstBase, -pci->metrics.ascent, + widthDst); + + /* find correct word in scanline and x offset within it + for left edge of glyph + */ + xoff = xchar + pci->metrics.leftSideBearing; + if (xoff > PLST) { + pdstSave++; + xoff &= PIM; + } else if (xoff < 0) { + xoff += PPW; + pdstSave--; + } + + for (d = 0; d < depthDst; d++) { + h = hSave; + pdst = pdstSave; + pdstSave += sizeDst; /* @@@ NEXT PLANE @@@ */ + pglyph = pglyphSave; + + if ((xoff + w) <= PPW) { + /* glyph all in one longword */ + maskpartialbits(xoff, w, startmask); + switch (rrops[d]) { + case RROP_WHITE: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst |= (SCRRIGHT(tmpSrc, xoff) & startmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_BLACK: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_INVERT: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst ^= (SCRRIGHT(tmpSrc, xoff) & startmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + } + } else { + /* glyph crosses longword boundary */ + maskPPWbits(xoff, w, startmask, endmask); + nFirst = PPW - xoff; + switch (rrops[d]) { + case RROP_WHITE: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst |= (SCRRIGHT(tmpSrc, xoff) & startmask); + *(pdst+1) |= (SCRLEFT(tmpSrc, nFirst) & endmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_BLACK: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask); + *(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_INVERT: + while (h--) { + getleftbits(pglyph, w, tmpSrc); + *pdst ^= (SCRRIGHT(tmpSrc, xoff) & startmask); + *(pdst+1) ^= (SCRLEFT(tmpSrc, nFirst) & endmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + } + } /* glyph crosses longwords boundary */ + } /* depth loop */ + /* update character origin */ + x += pci->metrics.characterWidth; + xchar += pci->metrics.characterWidth; + if (xchar > PLST) { + xchar -= PPW; + pdstBase++; + } else if (xchar < 0) { + xchar += PPW; + pdstBase--; + } + ppci++; + } /* while nglyph-- */ + break; + case rgnPART: + { + afbTEXTPOS *ppos; + int nbox; + BoxPtr pbox; + RegionPtr cclip; + int xpos; /* x position of char origin */ + int i; + BoxRec clip; + int leftEdge, rightEdge; + int topEdge, bottomEdge; + int glyphRow; /* first row of glyph not wholly + clipped out */ + int glyphCol; /* leftmost visible column of glyph */ + int getWidth; /* bits to get from glyph */ + + if(!(ppos = (afbTEXTPOS *)ALLOCATE_LOCAL(nglyph * sizeof(afbTEXTPOS)))) + return; + + pdstBase = afbScanlineNoBankSwitch(pdstBase, x, y, widthDst); + xpos = x; + xchar = xpos & PIM; + + for (i = 0; i < nglyph; i++) { + pci = ppci[i]; + + ppos[i].xpos = xpos; + ppos[i].xchar = xchar; + ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing; + ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing; + ppos[i].topEdge = y - pci->metrics.ascent; + ppos[i].bottomEdge = y + pci->metrics.descent; + ppos[i].pdstBase = pdstBase; + ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci); + + xpos += pci->metrics.characterWidth; + xchar += pci->metrics.characterWidth; + if (xchar > PLST) { + xchar &= PIM; + pdstBase++; + } else if (xchar < 0) { + xchar += PPW; + pdstBase--; + } + } + + cclip = pGC->pCompositeClip; + pbox = REGION_RECTS(cclip); + nbox = REGION_NUM_RECTS(cclip); + + /* HACK ALERT + since we continue out of the loop below so often, it + is easier to increment pbox at the top than at the end. + don't try this at home. + */ + pbox--; + while(nbox--) { + pbox++; + clip.x1 = max(bbox.x1, pbox->x1); + clip.y1 = max(bbox.y1, pbox->y1); + clip.x2 = min(bbox.x2, pbox->x2); + clip.y2 = min(bbox.y2, pbox->y2); + if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1)) + continue; + + for(i=0; i<nglyph; i++) { + pci = ppci[i]; + xchar = ppos[i].xchar; + + /* clip the left and right edges */ + if (ppos[i].leftEdge < clip.x1) + leftEdge = clip.x1; + else + leftEdge = ppos[i].leftEdge; + + if (ppos[i].rightEdge > clip.x2) + rightEdge = clip.x2; + else + rightEdge = ppos[i].rightEdge; + + w = rightEdge - leftEdge; + if (w <= 0) + continue; + + /* clip the top and bottom edges */ + if (ppos[i].topEdge < clip.y1) + topEdge = clip.y1; + else + topEdge = ppos[i].topEdge; + + if (ppos[i].bottomEdge > clip.y2) + bottomEdge = clip.y2; + else + bottomEdge = ppos[i].bottomEdge; + + hSave = bottomEdge - topEdge; + if (hSave <= 0) + continue; + + glyphRow = (topEdge - y) + pci->metrics.ascent; + widthGlyph = ppos[i].widthGlyph; + pglyphSave = FONTGLYPHBITS(pglyphBase, pci); + pglyphSave += (glyphRow * widthGlyph); + + glyphCol = (leftEdge - ppos[i].xpos) - + (pci->metrics.leftSideBearing); + getWidth = w + glyphCol; + + pdstSave = afbScanlineDelta(ppos[i].pdstBase, -(y-topEdge), + widthDst); + xoff = xchar + (leftEdge - ppos[i].xpos); + if (xoff > PLST) { + xoff &= PIM; + pdstSave++; + } else if (xoff < 0) { + xoff += PPW; + pdstSave--; + } + + for (d = 0; d < depthDst; d++) { + h = hSave; + pdst = pdstSave; + pdstSave += sizeDst; /* @@@ NEXT PLANE @@@ */ + pglyph = pglyphSave; + + if ((xoff + w) <= PPW) { + maskpartialbits(xoff, w, startmask); + switch (rrops[d]) { + case RROP_WHITE: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst |= (SCRRIGHT(tmpSrc, xoff) & startmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_BLACK: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_INVERT: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst ^= (SCRRIGHT(tmpSrc, xoff) & startmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + } + } else { + maskPPWbits(xoff, w, startmask, endmask); + nFirst = PPW - xoff; + switch (rrops[d]) { + case RROP_WHITE: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst |= (SCRRIGHT(tmpSrc, xoff) & startmask); + *(pdst+1) |= (SCRLEFT(tmpSrc, nFirst) & endmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_BLACK: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask); + *(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + case RROP_INVERT: + while (h--) { + getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc); + *pdst ^= (SCRRIGHT(tmpSrc, xoff) & startmask); + *(pdst+1) ^= (SCRLEFT(tmpSrc, nFirst) & endmask); + pglyph += widthGlyph; + afbScanlineInc(pdst, widthDst); + } + break; + } + } + } /* depth */ + } /* for each glyph */ + } /* while nbox-- */ + DEALLOCATE_LOCAL(ppos); + break; + } + + default: + break; + } +} diff --git a/afb/afbpntarea.c b/afb/afbpntarea.c new file mode 100644 index 000000000..239346ceb --- /dev/null +++ b/afb/afbpntarea.c @@ -0,0 +1,653 @@ +/* $XFree86: xc/programs/Xserver/afb/afbpntarea.c,v 3.1 2001/10/28 03:32:58 tsi Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbpntarea.c,v 5.7 94/04/17 20:28:29 dpw Exp $ */ + +#include "X.h" + +#include "windowstr.h" +#include "regionstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "afb.h" +#include "maskbits.h" + +/* + the solid fillers are called for rectangles and window backgrounds. + the boxes are already translated. + maybe this should always take a pixmap instead of a drawable? + + NOTE: + iy = ++iy < tileHeight ? iy : 0 +is equivalent to iy%= tileheight, and saves a division. +*/ + +/*ARGSUSED*/ +void +afbSolidFillArea (pDraw, nbox, pbox, rrops) + DrawablePtr pDraw; + int nbox; + BoxPtr pbox; + register unsigned char *rrops; +{ + int nlwidth; /* width in longwords of the drawable */ + int w; /* width of current box */ + register int h; /* height of current box */ + register PixelType *p; /* pointer to bits we're writing */ + register int nlw; /* loop version of nlwMiddle */ + register PixelType startmask; + register PixelType endmask; + /* masks for reggedy bits at either end of line */ + register int nlwExtra; + /* to get from right of box to left of next span */ + int nlwMiddle; /* number of longwords between sides of boxes */ + PixelType *pbits; /* pointer to start of drawable */ + PixelType *saveP; + int saveH; + int depthDst; + int sizeDst; + register int d; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + pbits); + + while (nbox--) { + w = pbox->x2 - pbox->x1; + saveH = pbox->y2 - pbox->y1; + + saveP = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth); + + if ( ((pbox->x1 & PIM) + w) < PPW) { + for (d = 0; d < depthDst; d++) { + h = saveH; + p = saveP; + saveP += sizeDst; /* @@@ NEXT PLANE @@@ */ + maskpartialbits(pbox->x1, w, startmask); + nlwExtra = nlwidth; + + switch (rrops[d]) { + case RROP_BLACK: + Duff(h, *p &= ~startmask; afbScanlineInc(p, nlwExtra)); + break; + case RROP_WHITE: + Duff(h, *p |= startmask; afbScanlineInc(p, nlwExtra)); + break; + case RROP_INVERT: + Duff(h, *p ^= startmask; afbScanlineInc(p, nlwExtra)); + break; + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ..) */ + } else { + maskbits(pbox->x1, w, startmask, endmask, nlwMiddle); + + for (d = 0; d < depthDst; d++) { + h = saveH; + p = saveP; + saveP += sizeDst; /* @@@ NEXT PLANE @@@ */ + nlwExtra = nlwidth - nlwMiddle; + + if (startmask && endmask) { + nlwExtra -= 1; + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + nlw = nlwMiddle; + *p &= ~startmask; + p++; + Duff(nlw, *p++ = 0); + *p &= ~endmask; + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_WHITE: + while (h--) { + nlw = nlwMiddle; + *p |= startmask; + p++; + Duff(nlw, *p++ = ~0); + *p |= endmask; + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_INVERT: + while (h--) { + nlw = nlwMiddle; + *p ^= startmask; + p++; + Duff(nlw, *p++ ^= ~0); + *p ^= endmask; + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_NOP: + break; + } + } else if (startmask && !endmask) { + nlwExtra -= 1; + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + nlw = nlwMiddle; + *p &= ~startmask; + p++; + Duff(nlw, *p++ = 0); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_WHITE: + while (h--) { + nlw = nlwMiddle; + *p |= startmask; + p++; + Duff(nlw, *p++ = ~0); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_INVERT: + while (h--) { + nlw = nlwMiddle; + *p ^= startmask; + p++; + Duff(nlw, *p++ ^= ~0); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_NOP: + break; + } + } else if (!startmask && endmask) { + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + nlw = nlwMiddle; + Duff(nlw, *p++ = 0); + *p &= ~endmask; + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_WHITE: + while (h--) { + nlw = nlwMiddle; + Duff(nlw, *p++ = ~0); + *p |= endmask; + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_INVERT: + while (h--) { + nlw = nlwMiddle; + Duff(nlw, *p++ ^= ~0); + *p ^= endmask; + afbScanlineInc(p, nlwExtra); + } + case RROP_NOP: + break; + } + } else { /* no ragged bits at either end */ + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + nlw = nlwMiddle; + Duff(nlw, *p++ = 0); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_WHITE: + while (h--) { + nlw = nlwMiddle; + Duff(nlw, *p++ = ~0); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_INVERT: + while (h--) { + nlw = nlwMiddle; + Duff(nlw, *p++ ^= ~0); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_NOP: + break; + } /* switch */ + } + } /* for (d = 0 ... ) */ + } + pbox++; + } +} + +/* stipple a list of boxes - + +you can use the reduced rasterop for stipples. if rrop is +black, AND the destination with (not stipple pattern). if rrop is +white OR the destination with the stipple pattern. if rrop is invert, +XOR the destination with the stipple pattern. +*/ + +/*ARGSUSED*/ +void +afbStippleAreaPPW (pDraw, nbox, pbox, pstipple, rrops) + DrawablePtr pDraw; + int nbox; + BoxPtr pbox; + PixmapPtr pstipple; + unsigned char *rrops; +{ + register PixelType *psrc; + /* pointer to bits in tile, if needed */ + int tileHeight; /* height of the tile */ + register PixelType srcpix; + + int nlwidth; /* width in longwords of the drawable */ + int w; /* width of current box */ + register int nlw; /* loop version of nlwMiddle */ + register PixelType *p; /* pointer to bits we're writing */ + register int h; /* height of current box */ + PixelType startmask; + PixelType endmask; /* masks for reggedy bits at either end of line */ + int nlwMiddle; /* number of longwords between sides of boxes */ + int nlwExtra; /* to get from right of box to left of next span */ + int sizeDst; + int depthDst; + int d; + int saveIy; + register int iy; /* index of current scanline in tile */ + PixelType *pbits; /* pointer to start of drawable */ + PixelType *pBase; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + pBase); + + tileHeight = pstipple->drawable.height; + psrc = (PixelType *)(pstipple->devPrivate.ptr); + + while (nbox--) { + w = pbox->x2 - pbox->x1; + saveIy = pbox->y1 % tileHeight; + pbits = pBase; + + if ( ((pbox->x1 & PIM) + w) < PPW) { + maskpartialbits(pbox->x1, w, startmask); + nlwExtra = nlwidth; + for (d = 0; d < depthDst; d++) { + p = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth); + pbits += sizeDst; /* @@@ NEXT PLANE @@@ */ + iy = saveIy; + h = pbox->y2 - pbox->y1; + + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + *p &= ~(srcpix & startmask); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_WHITE: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + *p |= (srcpix & startmask); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_INVERT: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + *p ^= (srcpix & startmask); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ...) */ + + } else { + maskbits(pbox->x1, w, startmask, endmask, nlwMiddle); + + for (d = 0; d < depthDst; d++) { + nlwExtra = nlwidth - nlwMiddle; + p = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth); + pbits += sizeDst; /* @@@ NEXT PLANE @@@ */ + iy = saveIy; + h = pbox->y2 - pbox->y1; + + if (startmask && endmask) { + nlwExtra -= 1; + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + *p &= ~(srcpix & startmask); + p++; + Duff (nlw, *p++ &= ~srcpix); + *p &= ~(srcpix & endmask); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_WHITE: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + *p |= (srcpix & startmask); + p++; + Duff (nlw, *p++ |= srcpix); + *p |= (srcpix & endmask); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_INVERT: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + *p ^= (srcpix & startmask); + p++; + Duff (nlw, *p++ ^= srcpix); + *p ^= (srcpix & endmask); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_NOP: + break; + } /* switch */ + } else if (startmask && !endmask) { + nlwExtra -= 1; + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + *p &= ~(srcpix & startmask); + p++; + Duff(nlw, *p++ &= ~srcpix); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_WHITE: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + *p |= (srcpix & startmask); + p++; + Duff(nlw, *p++ |= srcpix); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_INVERT: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + *p ^= (srcpix & startmask); + p++; + Duff(nlw, *p++ ^= srcpix); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_NOP: + break; + } /* switch */ + } else if (!startmask && endmask) { + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + Duff(nlw, *p++ &= ~srcpix); + *p &= ~(srcpix & endmask); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_WHITE: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + Duff(nlw, *p++ |= srcpix); + *p |= (srcpix & endmask); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_INVERT: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + Duff(nlw, *p++ ^= srcpix); + *p ^= (srcpix & endmask); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_NOP: + break; + } /* switch */ + } else { /* no ragged bits at either end */ + switch (rrops[d]) { + case RROP_BLACK: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + Duff(nlw, *p++ &= ~srcpix); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_WHITE: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + Duff(nlw, *p++ |= srcpix); + afbScanlineInc(p, nlwExtra); + } + break; + case RROP_INVERT: + while (h--) { + srcpix = psrc[iy]; + iy = ++iy < tileHeight ? iy : 0; + nlw = nlwMiddle; + Duff(nlw, *p++ ^= srcpix); + afbScanlineInc(p, nlwExtra); + } + break; + } /* switch */ + } + } /* for (d = ...) */ + } + pbox++; + } +} + +void +afbStippleArea (pDraw, nbox, pbox, pTile, xOff, yOff, rrops) + DrawablePtr pDraw; + int nbox; + BoxPtr pbox; + PixmapPtr pTile; + int xOff; + int yOff; + unsigned char *rrops; +{ + register PixelType *psrc; /* pointer to bits in tile, if needed */ + int nlwidth; /* width in longwords of the drawable */ + register int h; /* height of current box */ + register PixelType *pdst; /* pointer to bits we're writing */ + int sizeDst; + int depthDst; + int tileLine; + int iline; + int w, width, x, xSrc, ySrc, srcStartOver, nend; + int tlwidth, rem, tileWidth, tileHeight, endinc; + int saveW; + register int rop; + PixelType *psrcT; + int d; + int nstart; + PixelType startmask; + PixelType endmask; /* masks for reggedy bits at either end of line */ + int nlMiddle; /* number of longwords between sides of boxes */ + int iy; + PixelType *pBase; /* pointer to start of drawable */ + PixelType *saveP; + PixelType *pStartDst; + PixelType *pStartTile; + int saveH; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + pBase); + + tileHeight = pTile->drawable.height; + tileWidth = pTile->drawable.width; + tlwidth = pTile->devKind / sizeof (PixelType); + + xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth); + ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight); + + while (nbox--) { + saveW = pbox->x2 - pbox->x1; + iline = (pbox->y1 - ySrc) % tileHeight; + psrcT = (PixelType *) pTile->devPrivate.ptr; + tileLine = iline * tlwidth; + saveH = pbox->y2 - pbox->y1; + saveP = afbScanline(pBase, pbox->x1, pbox->y1, nlwidth); + + for (d = 0; d < depthDst; d++, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */ + h = saveH; + pStartDst = saveP; + pStartTile = psrcT + tileLine; + iy = iline; + + while (h--) { + x = pbox->x1; + width = saveW; + pdst = pStartDst; + rop = rrops[d]; + + while(width > 0) { + psrc = pStartTile; + w = min(tileWidth, width); + if((rem = (x - xSrc) % tileWidth) != 0) { + /* if we're in the middle of the tile, get + as many bits as will finish the span, or + as many as will get to the left edge of the tile, + or a longword worth, starting at the appropriate + offset in the tile. + */ + w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD); + endinc = rem / BITMAP_SCANLINE_PAD; + getandputrrop((psrc + endinc), (rem & PIM), (x & PIM), + w, pdst, rop) + if((x & PIM) + w >= PPW) + pdst++; + } else if(((x & PIM) + w) < PPW) { + /* doing < PPW bits is easy, and worth special-casing */ + putbitsrrop(*psrc, x & PIM, w, pdst, rop); + } else { + /* start at the left edge of the tile, + and put down as much as we can + */ + maskbits(x, w, startmask, endmask, nlMiddle); + + if (startmask) + nstart = PPW - (x & PIM); + else + nstart = 0; + if (endmask) + nend = (x + w) & PIM; + else + nend = 0; + + srcStartOver = nstart > PLST; + + if(startmask) { + putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop); + pdst++; + if(srcStartOver) + psrc++; + } + + while(nlMiddle--) { + getandputrrop0(psrc, nstart, PPW, pdst, rop); + pdst++; + psrc++; + } + + if(endmask) { + getandputrrop0(psrc, nstart, nend, pdst, rop); + } + } + x += w; + width -= w; + } /* while (width > 0) */ + + pStartDst += nlwidth; + if (++iy >= tileHeight) { + iy = 0; + pStartTile = psrcT; + } else + pStartTile += tlwidth; + + } /* while (h) */ + } /* for (d = ... ) */ + pbox++; + } /* for each box */ +} diff --git a/afb/afbpntwin.c b/afb/afbpntwin.c new file mode 100644 index 000000000..17d924059 --- /dev/null +++ b/afb/afbpntwin.c @@ -0,0 +1,124 @@ +/* $XFree86: xc/programs/Xserver/afb/afbpntwin.c,v 3.0 1996/08/18 01:45:50 dawes Exp $ */ +/* $XConsortium: afbpntwin.c,v 5.12 94/04/17 20:28:30 dpw Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#include "X.h" + +#include "windowstr.h" +#include "regionstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "afb.h" +#include "maskbits.h" +#include "mi.h" + +void +afbPaintWindow(pWin, pRegion, what) + WindowPtr pWin; + RegionPtr pRegion; + int what; +{ + register afbPrivWin *pPrivWin; + unsigned char rrops[AFB_MAX_DEPTH]; + + pPrivWin = (afbPrivWin *)(pWin->devPrivates[afbWindowPrivateIndex].ptr); + + switch (what) { + case PW_BACKGROUND: + switch (pWin->backgroundState) { + case None: + return; + case ParentRelative: + do { + pWin = pWin->parent; + } while (pWin->backgroundState == ParentRelative); + (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion, + what); + return; + case BackgroundPixmap: + if (pPrivWin->fastBackground) { + afbTileAreaPPWCopy((DrawablePtr)pWin, + REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), GXcopy, + pPrivWin->pRotatedBackground, ~0); + return; + } else { + afbTileAreaCopy((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), GXcopy, + pWin->background.pixmap, 0, 0, ~0); + return; + } + break; + case BackgroundPixel: + afbReduceRop(GXcopy, pWin->background.pixel, ~0, + pWin->drawable.depth, rrops); + afbSolidFillArea((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), rrops); + return; + } + break; + case PW_BORDER: + if (pWin->borderIsPixel) { + afbReduceRop(GXcopy, pWin->border.pixel, ~0, pWin->drawable.depth, + rrops); + afbSolidFillArea((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), rrops); + return; + } else if (pPrivWin->fastBorder) { + afbTileAreaPPWCopy((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), GXcopy, + pPrivWin->pRotatedBorder, ~0); + return; + } + break; + } + miPaintWindow(pWin, pRegion, what); +} diff --git a/afb/afbpolypnt.c b/afb/afbpolypnt.c new file mode 100644 index 000000000..da9f13d82 --- /dev/null +++ b/afb/afbpolypnt.c @@ -0,0 +1,145 @@ +/* $XFree86: xc/programs/Xserver/afb/afbpolypnt.c,v 3.1 1998/03/20 21:04:56 hohndel Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbpolypnt.c,v 5.6 94/04/17 20:28:30 dpw Exp $ */ + +#include "X.h" +#include "Xprotostr.h" +#include "pixmapstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "miscstruct.h" +#include "regionstr.h" +#include "scrnintstr.h" + +#include "afb.h" +#include "maskbits.h" + +void +afbPolyPoint(pDrawable, pGC, mode, npt, pptInit) + register DrawablePtr pDrawable; + GCPtr pGC; + int mode; /* Origin or Previous */ + int npt; + xPoint *pptInit; +{ + + register BoxPtr pbox; + register int nbox; + register int d; + + register PixelType *addrl; + PixelType *pBase; + PixelType *pBaseSave; + int nlwidth; + int sizeDst; + int depthDst; + + int nptTmp; + register xPoint *ppt; + + register int x; + register int y; + register unsigned char *rrops; + afbPrivGC *pGCPriv; + + pGCPriv = (afbPrivGC *) pGC->devPrivates[afbGCPrivateIndex].ptr; + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst, + pBaseSave); + + rrops = pGCPriv->rrops; + if ((mode == CoordModePrevious) && (npt > 1)) + for (ppt = pptInit + 1, nptTmp = npt - 1; --nptTmp >= 0; ppt++) { + ppt->x += (ppt-1)->x; + ppt->y += (ppt-1)->y; + } + + nbox = REGION_NUM_RECTS(pGC->pCompositeClip); + pbox = REGION_RECTS(pGC->pCompositeClip); + for (; --nbox >= 0; pbox++) + for (d = 0, pBase = pBaseSave; d < depthDst; d++, pBase += sizeDst) { /* @@@ NEXT PLANE @@@ */ + addrl = pBase; + + switch (rrops[d]) { + case RROP_BLACK: + for (ppt = pptInit, nptTmp = npt; --nptTmp >= 0; ppt++) { + x = ppt->x + pDrawable->x; + y = ppt->y + pDrawable->y; + if ((x >= pbox->x1) && (x < pbox->x2) && + (y >= pbox->y1) && (y < pbox->y2)) + *afbScanline(addrl, x, y, nlwidth) &= rmask[x & PIM]; + } + break; + + case RROP_WHITE: + for (ppt = pptInit, nptTmp = npt; --nptTmp >= 0; ppt++) { + x = ppt->x + pDrawable->x; + y = ppt->y + pDrawable->y; + if ((x >= pbox->x1) && (x < pbox->x2) && + (y >= pbox->y1) && (y < pbox->y2)) + *afbScanline(addrl, x, y, nlwidth) |= mask[x & PIM]; + } + break; + + case RROP_INVERT: + for (ppt = pptInit, nptTmp = npt; --nptTmp >= 0; ppt++) { + x = ppt->x + pDrawable->x; + y = ppt->y + pDrawable->y; + if ((x >= pbox->x1) && (x < pbox->x2) && + (y >= pbox->y1) && (y < pbox->y2)) + *afbScanline(addrl, x, y, nlwidth) ^= mask[x & PIM]; + } + break; + + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ...) */ +} diff --git a/afb/afbpushpxl.c b/afb/afbpushpxl.c new file mode 100644 index 000000000..688aec973 --- /dev/null +++ b/afb/afbpushpxl.c @@ -0,0 +1,256 @@ +/* $XFree86: xc/programs/Xserver/afb/afbpushpxl.c,v 3.1 1998/03/20 21:04:56 hohndel Exp $ */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbpushpxl.c,v 5.6 94/04/17 20:28:31 dpw Exp $ */ + +#include "X.h" +#include "gcstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "miscstruct.h" +#include "maskbits.h" +#include "regionstr.h" +#include "afb.h" + +/* afbSolidPP is courtesy of xhacks@csri.toronto.edu + + For fillStyle==FillSolid, a monochrome PushPixels can be reduced to + a ROP in the following way: (Note that the ROP is the same as the + result of ROP(src=0x3,dst=0x5)) + + src=0011 0000 0011 + dst=0101 0101 0101 + rop fg=0 fg=1 + GXclear 0x0 0000 0100 0100 0 + GXand 0x1 0001 0100 0101 s&d + GXandReverse 0x2 0010 0100 0110 s&~d + GXcopy 0x3 0011 0100 0111 s + GXandInverted 0x4 0100 0101 0100 ~s&d + GXnoop 0x5 0101 0101 0101 d + GXxor 0x6 0110 0101 0110 s^d + GXor 0x7 0111 0101 0111 s|d + GXnor 0x8 1000 0110 0100 ~s&~d + GXequiv 0x9 1001 0110 0101 ~s^d + GXinvert 0xa 1010 0110 0110 ~d + GXorReverse 0xb 1011 0110 0111 s|~d + GXcopyInverted 0xc 1100 0111 0100 ~s + GXorInverted 0xd 1101 0111 0101 ~s|d + GXnand 0xe 1110 0111 0110 ~s|~d + GXset 0xf 1111 0111 0111 1 + +For src=0: newRop = 0x4|(rop>>2) +For src=1: newRop = 0x4|(rop&3) +*/ + +/* afbSolidPP -- squeegees the forground color of pGC through pBitMap + * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may + * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit + * is set in the bitmap, the fill style is put onto the drawable using + * the GC's logical function. The drawable is not changed where the bitmap + * has a zero bit or outside the area covered by the stencil. + */ +void +afbSolidPP(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg) + GCPtr pGC; + PixmapPtr pBitMap; + DrawablePtr pDrawable; + int dx, dy, xOrg, yOrg; +{ + unsigned char alu; + RegionRec rgnDst; + DDXPointPtr pptSrc; + BoxRec srcBox; + register DDXPointPtr ppt; + register BoxPtr pbox; + int i; + + if (!pGC->planemask & 1) return; + + /* compute the reduced rop function */ + alu = pGC->alu; + if (!(pGC->fgPixel&1)) alu >>= 2; + alu = (alu & 0x3) | 0x4; + if (alu == GXnoop) return; + + srcBox.x1 = xOrg; + srcBox.y1 = yOrg; + srcBox.x2 = xOrg + dx; + srcBox.y2 = yOrg + dy; + REGION_INIT(pGC->pScreen, &rgnDst, &srcBox, 1); + + /* clip the shape of the dst to the destination composite clip */ + REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, pGC->pCompositeClip); + + if (!REGION_NIL(&rgnDst)) { + i = REGION_NUM_RECTS(&rgnDst); + pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec)); + if(pptSrc) { + for (pbox = REGION_RECTS(&rgnDst), ppt = pptSrc; --i >= 0; + pbox++, ppt++) { + ppt->x = pbox->x1 - xOrg; + ppt->y = pbox->y1 - yOrg; + } + afbDoBitblt((DrawablePtr)pBitMap, pDrawable, alu, &rgnDst, pptSrc, + pGC->planemask); + DEALLOCATE_LOCAL(pptSrc); + } + } + REGION_UNINIT(pGC->pScreen, &rgnDst); +} + +#define NPT 128 + +/* afbPushPixels -- squeegees the forground color of pGC through pBitMap + * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may + * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit + * is set in the bitmap, the fill style is put onto the drawable using + * the GC's logical function. The drawable is not changed where the bitmap + * has a zero bit or outside the area covered by the stencil. + */ +void +afbPushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg) + GCPtr pGC; + PixmapPtr pBitMap; + DrawablePtr pDrawable; + int dx, dy, xOrg, yOrg; +{ + int h, dxDivPPW, ibEnd; + PixelType *pwLineStart; + register PixelType *pw, *pwEnd; + register PixelType mask; + register int ib; + register PixelType w; + register int ipt; /* index into above arrays */ + Bool fInBox; + DDXPointRec pt[NPT]; + int width[NPT]; + + /* Now scan convert the pixmap and use the result to call fillspans in + * in the drawable with the original GC */ + ipt = 0; + dxDivPPW = dx/PPW; + for (h = 0; h < dy; h++) { + + pw = (PixelType *) + (((char *)(pBitMap->devPrivate.ptr))+(h * pBitMap->devKind)); + pwLineStart = pw; + /* Process all words which are fully in the pixmap */ + + fInBox = FALSE; + pwEnd = pwLineStart + dxDivPPW; + while(pw < pwEnd) { + w = *pw; + mask = endtab[1]; + for(ib = 0; ib < PPW; ib++) { + if(w & mask) { + if(!fInBox) { + pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; + pt[ipt].y = h + yOrg; + /* start new box */ + fInBox = TRUE; + } + } else { + if(fInBox) { + width[ipt] = ((pw - pwLineStart) << PWSH) + + ib + xOrg - pt[ipt].x; + if (++ipt >= NPT) { + (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, + width, TRUE); + ipt = 0; + } + /* end box */ + fInBox = FALSE; + } + } + mask = SCRRIGHT(mask, 1); + } + pw++; + } + ibEnd = dx & PIM; + if(ibEnd) { + /* Process final partial word on line */ + w = *pw; + mask = endtab[1]; + for(ib = 0; ib < ibEnd; ib++) { + if(w & mask) { + if(!fInBox) { + /* start new box */ + pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; + pt[ipt].y = h + yOrg; + fInBox = TRUE; + } + } else { + if(fInBox) { + /* end box */ + width[ipt] = ((pw - pwLineStart) << PWSH) + + ib + xOrg - pt[ipt].x; + if (++ipt >= NPT) { + (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, + width, TRUE); + ipt = 0; + } + fInBox = FALSE; + } + } + mask = SCRRIGHT(mask, 1); + } + } + /* If scanline ended with last bit set, end the box */ + if(fInBox) { + width[ipt] = dx + xOrg - pt[ipt].x; + if (++ipt >= NPT) { + (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE); + ipt = 0; + } + } + } + /* Flush any remaining spans */ + if (ipt) { + (*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE); + } +} diff --git a/afb/afbscrinit.c b/afb/afbscrinit.c new file mode 100644 index 000000000..d2b3fd02b --- /dev/null +++ b/afb/afbscrinit.c @@ -0,0 +1,244 @@ +/* $XFree86: xc/programs/Xserver/afb/afbscrinit.c,v 3.5 1998/11/22 10:36:59 dawes Exp $ */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbscrinit.c,v 5.17 94/04/17 20:28:34 dpw Exp $ */ + +#include "X.h" +#include "Xproto.h" /* for xColorItem */ +#include "Xmd.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "resource.h" +#include "colormap.h" +#include "afb.h" +#include "mistruct.h" +#include "dix.h" +#include "mi.h" +#include "mibstore.h" +#include "migc.h" +#include "servermd.h" + +#ifdef PIXMAP_PER_WINDOW +int frameWindowPrivateIndex; +#endif +int afbWindowPrivateIndex; +int afbGCPrivateIndex; +int afbScreenPrivateIndex; + +static unsigned long afbGeneration = 0; + +BSFuncRec afbBSFuncRec = { + afbSaveAreas, + afbRestoreAreas, + (BackingStoreSetClipmaskRgnProcPtr) 0, + (BackingStoreGetImagePixmapProcPtr) 0, + (BackingStoreGetSpansPixmapProcPtr) 0, +}; + +Bool +afbCloseScreen(index, pScreen) + int index; + ScreenPtr pScreen; +{ + int d; + DepthPtr depths = pScreen->allowedDepths; + + for (d = 0; d < pScreen->numDepths; d++) + xfree(depths[d].vids); + xfree(depths); + xfree(pScreen->visuals); + xfree(pScreen->devPrivates[afbScreenPrivateIndex].ptr); + return(TRUE); +} + +Bool +afbCreateScreenResources(pScreen) + ScreenPtr pScreen; +{ + Bool retval; + + pointer oldDevPrivate = pScreen->devPrivate; + + pScreen->devPrivate = pScreen->devPrivates[afbScreenPrivateIndex].ptr; + retval = miCreateScreenResources(pScreen); + + /* Modify screen's pixmap devKind value stored off devPrivate to + * be the width of a single plane in longs rather than the width + * of a chunky screen in longs as incorrectly setup by the mi routine. + */ + ((PixmapPtr)pScreen->devPrivate)->devKind = BitmapBytePad(pScreen->width); + pScreen->devPrivates[afbScreenPrivateIndex].ptr = pScreen->devPrivate; + pScreen->devPrivate = oldDevPrivate; + return(retval); +} + +Bool +afbAllocatePrivates(pScreen, pWinIndex, pGCIndex) + ScreenPtr pScreen; + int *pWinIndex, *pGCIndex; +{ + if (afbGeneration != serverGeneration) { +#ifdef PIXMAP_PER_WINDOW + frameWindowPrivateIndex = AllocateWindowPrivateIndex(); +#endif + afbWindowPrivateIndex = AllocateWindowPrivateIndex(); + afbGCPrivateIndex = AllocateGCPrivateIndex(); + afbGeneration = serverGeneration; + } + if (pWinIndex) + *pWinIndex = afbWindowPrivateIndex; + if (pGCIndex) + *pGCIndex = afbGCPrivateIndex; + + afbScreenPrivateIndex = AllocateScreenPrivateIndex(); + pScreen->GetWindowPixmap = afbGetWindowPixmap; + pScreen->SetWindowPixmap = afbSetWindowPixmap; + return(AllocateWindowPrivate(pScreen, afbWindowPrivateIndex, sizeof(afbPrivWin)) && + AllocateGCPrivate(pScreen, afbGCPrivateIndex, sizeof(afbPrivGC))); +} + +/* dts * (inch/dot) * (25.4 mm / inch) = mm */ +Bool +afbScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width) + register ScreenPtr pScreen; + pointer pbits; /* pointer to screen bitmap */ + int xsize, ysize; /* in pixels */ + int dpix, dpiy; /* dots per inch */ + int width; /* pixel width of frame buffer */ +{ + VisualPtr visuals; + DepthPtr depths; + int nvisuals; + int ndepths; + int rootdepth; + VisualID defaultVisual; + pointer oldDevPrivate; + + rootdepth = 0; + if (!afbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth, + &defaultVisual, 256, 8)) { + ErrorF("afbInitVisuals: FALSE\n"); + return FALSE; + } + if (!afbAllocatePrivates(pScreen,(int *)NULL, (int *)NULL)) { + ErrorF("afbAllocatePrivates: FALSE\n"); + return FALSE; + } + + pScreen->defColormap = (Colormap)FakeClientID(0); + /* whitePixel, blackPixel */ + pScreen->blackPixel = 0; + pScreen->whitePixel = 0; + pScreen->QueryBestSize = afbQueryBestSize; + /* SaveScreen */ + pScreen->GetImage = afbGetImage; + pScreen->GetSpans = afbGetSpans; + pScreen->CreateWindow = afbCreateWindow; + pScreen->DestroyWindow = afbDestroyWindow; + pScreen->PositionWindow = afbPositionWindow; + pScreen->ChangeWindowAttributes = afbChangeWindowAttributes; + pScreen->RealizeWindow = afbMapWindow; + pScreen->UnrealizeWindow = afbUnmapWindow; + pScreen->PaintWindowBackground = afbPaintWindow; + pScreen->PaintWindowBorder = afbPaintWindow; + pScreen->CopyWindow = afbCopyWindow; + pScreen->CreatePixmap = afbCreatePixmap; + pScreen->DestroyPixmap = afbDestroyPixmap; + pScreen->RealizeFont = afbRealizeFont; + pScreen->UnrealizeFont = afbUnrealizeFont; + pScreen->CreateGC = afbCreateGC; + pScreen->CreateColormap = afbInitializeColormap; + pScreen->DestroyColormap = (void (*)())NoopDDA; + pScreen->InstallColormap = afbInstallColormap; + pScreen->UninstallColormap = afbUninstallColormap; + pScreen->ListInstalledColormaps = afbListInstalledColormaps; + pScreen->StoreColors = (void (*)())NoopDDA; + pScreen->ResolveColor = afbResolveColor; + pScreen->BitmapToRegion = afbPixmapToRegion; + oldDevPrivate = pScreen->devPrivate; + if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, rootdepth, + ndepths, depths, defaultVisual, nvisuals, visuals)) { + ErrorF("miScreenInit: FALSE\n"); + return FALSE; + } + + pScreen->CloseScreen = afbCloseScreen; + pScreen->CreateScreenResources = afbCreateScreenResources; + pScreen->BackingStoreFuncs = afbBSFuncRec; + + pScreen->devPrivates[afbScreenPrivateIndex].ptr = pScreen->devPrivate; + pScreen->devPrivate = oldDevPrivate; + + return TRUE; +} + +PixmapPtr +afbGetWindowPixmap(pWin) + WindowPtr pWin; +{ +#ifdef PIXMAP_PER_WINDOW + return (PixmapPtr)(pWin->devPrivates[frameWindowPrivateIndex].ptr); +#else + ScreenPtr pScreen = pWin->drawable.pScreen; + + return (* pScreen->GetScreenPixmap)(pScreen); +#endif +} + +void +afbSetWindowPixmap(pWin, pPix) + WindowPtr pWin; + PixmapPtr pPix; +{ +#ifdef PIXMAP_PER_WINDOW + pWin->devPrivates[frameWindowPrivateIndex].ptr = (pointer)pPix; +#else + (* pWin->drawable.pScreen->SetScreenPixmap)(pPix); +#endif +} diff --git a/afb/afbsetsp.c b/afb/afbsetsp.c new file mode 100644 index 000000000..93331b857 --- /dev/null +++ b/afb/afbsetsp.c @@ -0,0 +1,265 @@ +/* $XFree86: xc/programs/Xserver/afb/afbsetsp.c,v 3.3 2001/10/28 03:32:58 tsi Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbsetsp.c,v 5.8 94/04/17 20:28:34 dpw Exp $ */ + +#include "X.h" +#include "Xmd.h" + +#include "misc.h" +#include "regionstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "afb.h" +#include "maskbits.h" + +#include "servermd.h" + + +/* afbSetScanline -- copies the bits from psrc to the drawable starting at + * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc + * starts on the scanline. (I.e., if this scanline passes through multiple + * boxes, we may not want to start grabbing bits at psrc but at some offset + * further on.) + */ +void +afbSetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst, + sizeDst, depthDst, sizeSrc) + int y; + int xOrigin; /* where this scanline starts */ + int xStart; /* first bit to use from scanline */ + int xEnd; /* last bit to use from scanline + 1 */ + register PixelType *psrc; + register int alu; /* raster op */ + PixelType *pdstBase; /* start of the drawable */ + int widthDst; /* width of drawable in words */ + int sizeDst; + int depthDst; + int sizeSrc; +{ + int w; /* width of scanline in bits */ + register PixelType *pdst; /* where to put the bits */ + register PixelType tmpSrc; /* scratch buffer to collect bits in */ + int dstBit; /* offset in bits from beginning of + * word */ + register int nstart; /* number of bits from first partial */ + register int nend; /* " " last partial word */ + int offSrc; + PixelType startmask, endmask; + PixelType *savePsrc = psrc + ((xStart - xOrigin) >> PWSH); + int nlMiddle, nl; + int d; + + for (d = 0; d < depthDst; d++) { + pdst = afbScanline(pdstBase, xStart, y, widthDst) + sizeDst * d; /* @@@ NEXT PLANE @@@ */ + psrc = savePsrc + sizeSrc * d; /* @@@ NEXT PLANE @@@ */ + offSrc = (xStart - xOrigin) & PIM; + w = xEnd - xStart; + dstBit = xStart & PIM; + + if (dstBit + w <= PPW) { + getandputrop(psrc, offSrc, dstBit, w, pdst, alu) + } else { + maskbits(xStart, w, startmask, endmask, nlMiddle); + if (startmask) + nstart = PPW - dstBit; + else + nstart = 0; + if (endmask) + nend = xEnd & PIM; + else + nend = 0; + if (startmask) { + getandputrop(psrc, offSrc, dstBit, nstart, pdst, alu) + pdst++; + offSrc += nstart; + if (offSrc > PLST) { + psrc++; + offSrc -= PPW; + } + } + nl = nlMiddle; + while (nl--) { + getbits(psrc, offSrc, PPW, tmpSrc); + DoRop(*pdst, alu, tmpSrc, *pdst); + pdst++; + psrc++; + } + if (endmask) { + getandputrop0(psrc, offSrc, nend, pdst, alu); + } + } + } +} + + + +/* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at + * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines + * are in increasing Y order. + * Source bit lines are server scanline padded so that they always begin + * on a word boundary. + */ +void +afbSetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted) + DrawablePtr pDrawable; + GCPtr pGC; + char *pcharsrc; + register DDXPointPtr ppt; + int *pwidth; + int nspans; + int fSorted; +{ + PixelType *psrc = (PixelType *)pcharsrc; + PixelType *pdstBase; /* start of dst bitmap */ + int widthDst; /* width of bitmap in words */ + int sizeDst; + int depthDst; + int sizeSrc = 0; + register BoxPtr pbox, pboxLast, pboxTest; + register DDXPointPtr pptLast; + int alu; + RegionPtr prgnDst; + int xStart, xEnd; + int yMax; + + alu = pGC->alu; + prgnDst = pGC->pCompositeClip; + + pptLast = ppt + nspans; + + yMax = pDrawable->y + (int) pDrawable->height; + afbGetPixelWidthSizeDepthAndPointer(pDrawable, widthDst, sizeDst, depthDst, + pdstBase); + + pbox = REGION_RECTS(prgnDst); + pboxLast = pbox + REGION_NUM_RECTS(prgnDst); + + if(fSorted) { + /* scan lines sorted in ascending order. Because they are sorted, we + * don't have to check each scanline against each clip box. We can be + * sure that this scanline only has to be clipped to boxes at or after the + * beginning of this y-band + */ + pboxTest = pbox; + while(ppt < pptLast) { + pbox = pboxTest; + if(ppt->y >= yMax) + break; + while(pbox < pboxLast) { + if(pbox->y1 > ppt->y) { + /* scanline is before clip box */ + break; + } else if(pbox->y2 <= ppt->y) { + /* clip box is before scanline */ + pboxTest = ++pbox; + continue; + } else if(pbox->x1 > ppt->x + *pwidth) { + /* clip box is to right of scanline */ + break; + } else if(pbox->x2 <= ppt->x) { + /* scanline is to right of clip box */ + pbox++; + continue; + } + + /* at least some of the scanline is in the current clip box */ + xStart = max(pbox->x1, ppt->x); + xEnd = min(ppt->x + *pwidth, pbox->x2); + sizeSrc = PixmapWidthInPadUnits(*pwidth, 1); + afbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu, pdstBase, + widthDst, sizeDst, depthDst, sizeSrc); + if(ppt->x + *pwidth <= pbox->x2) { + /* End of the line, as it were */ + break; + } else + pbox++; + } + /* We've tried this line against every box; it must be outside them + * all. move on to the next point */ + ppt++; + psrc += sizeSrc * depthDst; + pwidth++; + } + } else { + /* scan lines not sorted. We must clip each line against all the boxes */ + while(ppt < pptLast) { + if(ppt->y >= 0 && ppt->y < yMax) { + for(pbox = REGION_RECTS(prgnDst); pbox< pboxLast; pbox++) { + if(pbox->y1 > ppt->y) { + /* rest of clip region is above this scanline, + * skip it */ + break; + } + if(pbox->y2 <= ppt->y) { + /* clip box is below scanline */ + pbox++; + break; + } + if(pbox->x1 <= ppt->x + *pwidth && + pbox->x2 > ppt->x) { + xStart = max(pbox->x1, ppt->x); + xEnd = min(pbox->x2, ppt->x + *pwidth); + sizeSrc = PixmapWidthInPadUnits(*pwidth, 1); + afbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu, + pdstBase, widthDst, sizeDst, depthDst, + sizeSrc); + } + + } + } + psrc += sizeSrc * depthDst; + ppt++; + pwidth++; + } + } +} diff --git a/afb/afbtegblt.c b/afb/afbtegblt.c new file mode 100644 index 000000000..b12eeb252 --- /dev/null +++ b/afb/afbtegblt.c @@ -0,0 +1,584 @@ +/* $XFree86: xc/programs/Xserver/afb/afbtegblt.c,v 3.2 2001/10/28 03:32:58 tsi Exp $ */ +/* $XConsortium: afbtegblt.c,v 5.14 94/04/17 20:28:35 dpw Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "afb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "maskbits.h" + +/* + this works for fonts with glyphs <= PPW bits wide. + + This should be called only with a terminal-emulator font; +this means that the FIXED_METRICS flag is set, and that +glyphbounds == charbounds. + + in theory, this goes faster; even if it doesn't, it reduces the +flicker caused by writing a string over itself with image text (since +the background gets repainted per character instead of per string.) +this seems to be important for some converted X10 applications. + + Image text looks at the bits in the glyph and the fg and bg in the +GC. it paints a rectangle, as defined in the protocol dcoument, +and the paints the characters. + +*/ + +#if defined(NO_3_60_CG4) && defined(FASTPUTBITS) && defined(FASTGETBITS) +#define FASTCHARS +#endif + +/* + * this macro "knows" that only characters <= 8 bits wide will + * fit this case (which is why it is independent of GLYPHPADBYTES) + */ + +#if (BITMAP_BIT_ORDER == MSBFirst) && (GLYPHPADBYTES != 4) +#if GLYPHPADBYTES == 1 +#define ShiftAmnt 24 +#else +#define ShiftAmnt 16 +#endif + +/* + * Note: for BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER, SCRRIGHT() evaluates its + * first argument more than once. Thus the imbedded char++ have to be moved. + * (DHD) + */ +#if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER +#if PPW == 32 +#define GetBits4 c = (*char1++ << ShiftAmnt) | \ + SCRRIGHT (*char2++ << ShiftAmnt, xoff2) | \ + SCRRIGHT (*char3++ << ShiftAmnt, xoff3) | \ + SCRRIGHT (*char4++ << ShiftAmnt, xoff4); +#else /* PPW */ +#define GetBits4 c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 ) | \ + (SCRRIGHT (*char2++ << ShiftAmnt, xoff2) << 32 ) | \ + (SCRRIGHT (*char3++ << ShiftAmnt, xoff3) << 32 ) | \ + (SCRRIGHT (*char4++ << ShiftAmnt, xoff4) << 32 ) | \ + (*char5++ << ShiftAmnt) | \ + SCRRIGHT (*char6++ << ShiftAmnt, xoff6) | \ + SCRRIGHT (*char7++ << ShiftAmnt, xoff7) | \ + SCRRIGHT (*char8++ << ShiftAmnt, xoff8); +#endif /* PPW */ +#else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */ +#if PPW == 32 +#define GetBits4 c = (*char1++ << ShiftAmnt) | \ + SCRRIGHT (*char2 << ShiftAmnt, xoff2) | \ + SCRRIGHT (*char3 << ShiftAmnt, xoff3) | \ + SCRRIGHT (*char4 << ShiftAmnt, xoff4); \ + char2++; char3++; char4++; +#else /* PPW == 64 */ +#define GetBits4 c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 ) | \ + (SCRRIGHT (*char2 << ShiftAmnt, xoff2) << 32 ) | \ + (SCRRIGHT (*char3 << ShiftAmnt, xoff3) << 32 ) | \ + (SCRRIGHT (*char4 << ShiftAmnt, xoff4) << 32 ) | \ + (*char5++ << ShiftAmnt) | \ + SCRRIGHT (*char6 << ShiftAmnt, xoff6) | \ + SCRRIGHT (*char7 << ShiftAmnt, xoff7) | \ + SCRRIGHT (*char8 << ShiftAmnt, xoff8); \ + char2++; char3++; char4++; char6++; char7++; char8++; +#endif /* PPW */ +#endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */ + +#else /* (BITMAP_BIT_ORDER != MSBFirst) || (GLYPHPADBYTES == 4) */ + +#if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER +#if PPW == 32 +#define GetBits4 c = *char1++ | \ + SCRRIGHT (*char2++, xoff2) | \ + SCRRIGHT (*char3++, xoff3) | \ + SCRRIGHT (*char4++, xoff4); +#else /* PPW == 64 */ +#define GetBits4 c = (unsigned long)(((*char1++) << 64 ) | \ + (SCRRIGHT (*char2++, xoff2) << 64 ) | \ + (SCRRIGHT (*char3++, xoff3) << 64 ) | \ + (SCRRIGHT (*char4++, xoff4) << 64 ) | \ + SCRRIGHT (*char5++, xoff5) | \ + SCRRIGHT (*char6++, xoff6) | \ + SCRRIGHT (*char7++, xoff7) | \ + SCRRIGHT (*char8++, xoff8)); +#endif /* PPW */ +#else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */ +#if PPW == 32 +#define GetBits4 c = *char1++ | \ + SCRRIGHT (*char2, xoff2) | \ + SCRRIGHT (*char3, xoff3) | \ + SCRRIGHT (*char4, xoff4); \ + char2++; char3++; char4++; +#else /* PPW == 64 */ +#define GetBits4 c = (unsigned long)(((*char1++) << 64 ) | \ + (SCRRIGHT (*char2, xoff2) << 64 ) | \ + (SCRRIGHT (*char3, xoff3) << 64 ) | \ + (SCRRIGHT (*char4, xoff4) << 64 ) | \ + SCRRIGHT (*char5, xoff5) | \ + SCRRIGHT (*char6, xoff6) | \ + SCRRIGHT (*char7, xoff7) | \ + SCRRIGHT (*char8, xoff8)); \ + char2++; char3++; char4++; \ + char5++; char6++; char7++; char8++; +#endif /* PPW */ +#endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */ + +#endif /* BITMAP_BIT_ORDER && GLYPHPADBYTES */ + + +#if GLYPHPADBYTES == 1 +typedef unsigned char *glyphPointer; +#define USE_LEFTBITS +#endif + +#if GLYPHPADBYTES == 2 +typedef unsigned short *glyphPointer; +#define USE_LEFTBITS +#endif + +#if GLYPHPADBYTES == 4 +typedef unsigned int *glyphPointer; +#endif + +#ifdef USE_LEFTBITS +#define GetBits1 getleftbits (char1, widthGlyph, c); \ + c &= glyphMask; \ + char1 = (glyphPointer) (((char *) char1) + glyphBytes); +#else +#define GetBits1 c = *char1++; +#endif + +void +afbTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) + DrawablePtr pDrawable; + GC *pGC; + int x, y; + unsigned int nglyph; + CharInfoPtr *ppci; /* array of character info */ + pointer pglyphBase; /* start of array of glyphs */ +{ + FontPtr pfont = pGC->font; + int widthDst; + PixelType *pdstBase; /* pointer to longword with top row + of current glyph */ + + int h; /* height of glyph and char */ + register int xpos; /* current x */ + int ypos; /* current y */ + int widthGlyph; + + int hTmp; /* counter for height */ + register PixelType startmask, endmask; + int nfirst; /* used if glyphs spans a longword boundary */ + BoxRec bbox; /* for clipping */ + int widthGlyphs; + int sizeDst; + int depthDst; + PixelType *saveDst; + register PixelType *dst; + register PixelType c; + register int d; + register int xoff1, xoff2, xoff3, xoff4; + register glyphPointer char1, char2, char3, char4; + glyphPointer schar1, schar2, schar3, schar4; +#if PPW == 64 + register int xoff5, xoff6, xoff7, xoff8; + register glyphPointer char5, char6, char7, char8; + glyphPointer schar5, schar6, schar7, schar8; +#endif /* PPW */ + + unsigned char *rrops; +#ifdef USE_LEFTBITS + register PixelType glyphMask; + register PixelType tmpSrc; + register int glyphBytes; +#endif + + afbGetPixelWidthSizeDepthAndPointer(pDrawable, widthDst, sizeDst, depthDst, + pdstBase); + + xpos = x + pDrawable->x; + ypos = y + pDrawable->y; + + widthGlyph = FONTMAXBOUNDS(pfont,characterWidth); + h = FONTASCENT(pfont) + FONTDESCENT(pfont); + + xpos += FONTMAXBOUNDS(pfont,leftSideBearing); + ypos -= FONTASCENT(pfont); + + rrops = ((afbPrivGCPtr) pGC->devPrivates[afbGCPrivateIndex].ptr)->rropOS; + + bbox.x1 = xpos; + bbox.x2 = xpos + (widthGlyph * nglyph); + bbox.y1 = ypos; + bbox.y2 = ypos + h; + + switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox)) { + case rgnPART: + /* this is the WRONG thing to do, but it works. + calling the non-terminal text is easy, but slow, given + what we know about the font. + + the right thing to do is something like: + for each clip rectangle + compute at which row the glyph starts to be in it, + and at which row the glyph ceases to be in it + compute which is the first glyph inside the left + edge, and the last one inside the right edge + draw a fractional first glyph, using only + the rows we know are in + draw all the whole glyphs, using the appropriate rows + draw any pieces of the last glyph, using the right rows + + this way, the code would take advantage of knowing that + all glyphs are the same height and don't overlap. + + one day... + */ + afbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + case rgnOUT: + return; + } + pdstBase = afbScanlineDeltaNoBankSwitch(pdstBase, ypos, widthDst); + widthGlyphs = widthGlyph * PGSZB; + +#ifdef USE_LEFTBITS + glyphMask = endtab[widthGlyph]; + glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci); +#endif + + if (nglyph >= PGSZB && widthGlyphs <= PPW) { + while (nglyph >= PGSZB) { + nglyph -= PGSZB; + xoff1 = xpos & PIM; + xoff2 = widthGlyph; + xoff3 = xoff2 + widthGlyph; + xoff4 = xoff3 + widthGlyph; +#if PPW == 64 + xoff5 = xoff4 + widthGlyph; + xoff6 = xoff5 + widthGlyph; + xoff7 = xoff6 + widthGlyph; + xoff8 = xoff7 + widthGlyph; +#endif /* PPW */ + schar1 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++)); + schar2 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++)); + schar3 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++)); + schar4 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++)); +#if PPW == 64 + schar5 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++)); + schar6 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++)); + schar7 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++)); + schar8 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++)); +#endif /* PPW */ + + hTmp = h; + saveDst = afbScanlineOffset(pdstBase, (xpos >> PWSH)); /* switch now */ + +#ifndef FASTCHARS + if (xoff1 + widthGlyphs <= PPW) { + maskpartialbits (xoff1, widthGlyphs, startmask); +#endif + for (d = 0; d < depthDst; d++) { + hTmp = h; + dst = saveDst; + saveDst += sizeDst; /* @@@ NEXT PLANE @@@ */ + + switch (rrops[d]) { + case RROP_BLACK: + while (hTmp--) { +#ifdef FASTCHARS + FASTPUTBITS(0, xoff1, widthGlyphs, dst); +#else + *(dst) &= ~startmask; +#endif + afbScanlineInc(dst, widthDst); + } + break; + case RROP_WHITE: + while (hTmp--) { +#ifdef FASTCHARS + FASTPUTBITS(~0, xoff1, widthGlyphs, dst); +#else + *(dst) |= startmask; +#endif + afbScanlineInc(dst, widthDst); + } + break; + case RROP_INVERT: + char1 = schar1; + char2 = schar2; + char3 = schar3; + char4 = schar4; + /* XXX */ + while (hTmp--) { + GetBits4 +#ifdef FASTCHARS +# if BITMAP_BIT_ORDER == MSBFirst + c >>= PPW - widthGlyphs; +# endif + FASTPUTBITS(~c, xoff1, widthGlyphs, dst); +#else + *(dst) = ((*dst) & ~startmask) | (~SCRRIGHT(c, xoff1) & startmask); +#endif + afbScanlineInc(dst, widthDst); + } + break; + case RROP_COPY: + char1 = schar1; + char2 = schar2; + char3 = schar3; + char4 = schar4; + + while (hTmp--) { + GetBits4 +#ifdef FASTCHARS +# if BITMAP_BIT_ORDER == MSBFirst + c >>= PPW - widthGlyphs; +#endif + FASTPUTBITS(c, xoff1, widthGlyphs, dst); +#else + *(dst) = ((*dst) & ~startmask) | (SCRRIGHT(c, xoff1) & startmask); +#endif + afbScanlineInc(dst, widthDst); + } + break; + case RROP_NOP: + break; + } /* switch (rrops[d]) */ + } /* for (d = ... ) */ +#ifndef FASTCHARS + } else { + maskPPWbits (xoff1, widthGlyphs, startmask, endmask); + nfirst = PPW - xoff1; + for (d = 0; d < depthDst; d++) { + hTmp = h; + dst = saveDst; + saveDst += sizeDst; /* @@@ NEXT PLANE @@@ */ + + switch (rrops[d]) { + case RROP_BLACK: + while (hTmp--) { + dst[0] &= ~startmask; + dst[1] &= ~endmask; + afbScanlineInc(dst, widthDst); + } + break; + case RROP_WHITE: + while (hTmp--) { + dst[0] |= startmask; + dst[1] |= endmask; + afbScanlineInc(dst, widthDst); + } + break; + case RROP_INVERT: + char1 = schar1; + char2 = schar2; + char3 = schar3; + char4 = schar4; + + while (hTmp--) { + GetBits4 + dst[0] = (dst[0] & ~startmask) | (~SCRRIGHT(c,xoff1) & startmask); + dst[1] = (dst[1] & ~endmask) | (~SCRLEFT(c,nfirst) & endmask); + afbScanlineInc(dst, widthDst); + } + break; + case RROP_COPY: + char1 = schar1; + char2 = schar2; + char3 = schar3; + char4 = schar4; + + while (hTmp--) { + GetBits4 + dst[0] = (dst[0] & ~startmask) | (SCRRIGHT(c,xoff1) & startmask); + dst[1] = (dst[1] & ~endmask) | (SCRLEFT(c,nfirst) & endmask); + afbScanlineInc(dst, widthDst); + } + break; + + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ... ) */ + } +#endif + xpos += widthGlyphs; + } + } + + while(nglyph--) { + xoff1 = xpos & PIM; + schar1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++)); + hTmp = h; + saveDst = afbScanlineOffset(pdstBase, (xpos >> PWSH)); + + if (xoff1 + widthGlyph <= PPW) { + maskpartialbits (xoff1, widthGlyph, startmask); + + for (d = 0; d < depthDst; d++) { + hTmp = h; + dst = saveDst; + saveDst += sizeDst; /* @@@ NEXT PLANE @@@ */ + char1 = schar1; + + switch (rrops[d]) { + case RROP_BLACK: + while (hTmp--) { + (*dst) &= ~startmask; + afbScanlineInc(dst, widthDst); + } + break; + case RROP_WHITE: + while (hTmp--) { + (*dst) |= startmask; + afbScanlineInc(dst, widthDst); + } + break; + case RROP_INVERT: + while (hTmp--) { +#ifdef FASTCHARS +#ifdef USE_LEFTBITS + FASTGETBITS (char1,0,widthGlyph,c); + char1 = (glyphPointer) (((char *) char1) + glyphBytes); +#else + c = *char1++; +#if BITMAP_BIT_ORDER == MSBFirst + c >>= PPW - widthGlyph; +#endif +#endif + FASTPUTBITS (~c,xoff1,widthGlyph,dst); +#else + GetBits1 + (*dst) = ((*dst) & ~startmask) | (~SCRRIGHT(c, xoff1) & startmask); +#endif + afbScanlineInc(dst, widthDst); + } + break; + case RROP_COPY: + while (hTmp--) { +#ifdef FASTCHARS +#ifdef USE_LEFTBITS + FASTGETBITS (char1,0,widthGlyph,c); + char1 = (glyphPointer) (((char *) char1) + glyphBytes); +#else + c = *char1++; +#if BITMAP_BIT_ORDER == MSBFirst + c >>= PPW - widthGlyph; +#endif +#endif + FASTPUTBITS (c,xoff1,widthGlyph,dst); +#else + GetBits1 + (*dst) = ((*dst) & ~startmask) | (SCRRIGHT(c, xoff1) & startmask); +#endif + afbScanlineInc(dst, widthDst); + } + break; + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ...) */ + } else { + maskPPWbits (xoff1, widthGlyph, startmask, endmask); + nfirst = PPW - xoff1; + + for (d = 0; d < depthDst; d++) { + hTmp = h; + dst = saveDst; + saveDst += sizeDst; /* @@@ NEXT PLANE @@@ */ + char1 = schar1; + + switch (rrops[d]) { + case RROP_BLACK: + while (hTmp--) { + dst[0] &= ~startmask; + dst[1] &= ~endmask; + afbScanlineInc(dst, widthDst); + } + break; + case RROP_WHITE: + while (hTmp--) { + dst[0] |= startmask; + dst[1] |= endmask; + afbScanlineInc(dst, widthDst); + } + break; + case RROP_INVERT: + while (hTmp--) { + GetBits1 + dst[0] = (dst[0] & ~startmask) | (~SCRRIGHT(c,xoff1) & startmask); + dst[1] = (dst[1] & ~endmask) | (~SCRLEFT(c,nfirst) & endmask); + afbScanlineInc(dst, widthDst); + } + break; + case RROP_COPY: + while (hTmp--) { + GetBits1 + dst[0] = (dst[0] & ~startmask) | (SCRRIGHT(c,xoff1) & startmask); + dst[1] = (dst[1] & ~endmask) | (SCRLEFT(c,nfirst) & endmask); + afbScanlineInc(dst, widthDst); + } + break; + case RROP_NOP: + break; + } /* switch */ + } /* for (d = ...) */ + } + + xpos += widthGlyph; + } +} diff --git a/afb/afbtile.c b/afb/afbtile.c new file mode 100644 index 000000000..687bed0a6 --- /dev/null +++ b/afb/afbtile.c @@ -0,0 +1,857 @@ +/* $XFree86: xc/programs/Xserver/afb/afbtile.c,v 3.3 2001/10/28 03:32:59 tsi Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: afbtile.c,v 5.8 94/04/17 20:28:36 dpw Exp $ */ + +#include "X.h" + +#include "windowstr.h" +#include "regionstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "afb.h" + +#include "maskbits.h" + +#include "mergerop.h" +/* + + the boxes are already translated. + + NOTE: + iy = ++iy < tileHeight ? iy : 0 +is equivalent to iy%= tileheight, and saves a division. +*/ + +/* + tile area with a PPW bit wide pixmap +*/ +void +MROP_NAME(afbTileAreaPPW)(pDraw, nbox, pbox, alu, ptile, planemask) + DrawablePtr pDraw; + int nbox; + BoxPtr pbox; + int alu; + PixmapPtr ptile; + unsigned long planemask; +{ + register PixelType *psrc; + /* pointer to bits in tile, if needed */ + int tileHeight; /* height of the tile */ + register PixelType srcpix; + int nlwidth; /* width in longwords of the drawable */ + int w; /* width of current box */ + MROP_DECLARE_REG () + register int h; /* height of current box */ + register int nlw; /* loop version of nlwMiddle */ + register PixelType *p; /* pointer to bits we're writing */ + int sizeDst; + int depthDst; + int tlwidth; + register int d; + PixelType startmask; + PixelType endmask; /* masks for reggedy bits at either end of line */ + int nlwMiddle; /* number of longwords between sides of boxes */ + int nlwExtra; /* to get from right of box to left of next span */ + register int iy; /* index of current scanline in tile */ + PixelType *pbits; /* pointer to start of drawable */ + PixelType *saveP; + PixelType *pSaveSrc; + int saveH; + int saveIY; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + pbits); + + MROP_INITIALIZE(alu,~0) + + tileHeight = ptile->drawable.height; + tlwidth = ptile->devKind / sizeof (PixelType); + pSaveSrc = (PixelType *)(ptile->devPrivate.ptr); + + while (nbox--) { + w = pbox->x2 - pbox->x1; + saveH = pbox->y2 - pbox->y1; + saveIY = pbox->y1 % tileHeight; + saveP = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth); + psrc = pSaveSrc; + + if (((pbox->x1 & PIM) + w) < PPW) { + maskpartialbits(pbox->x1, w, startmask); + nlwExtra = nlwidth; + for (d = 0; d < depthDst; d++, saveP += sizeDst, psrc += tileHeight) { /* @@@ NEXT PLANE @@@ */ + if (!(planemask & (1 << d))) + continue; + + p = saveP; + h = saveH; + iy = saveIY; + + while (h--) { + srcpix = psrc[iy]; + iy++; + if (iy == tileHeight) + iy = 0; + *p = MROP_MASK(srcpix,*p,startmask); + afbScanlineInc(p, nlwExtra); + } + } + } else { + maskbits(pbox->x1, w, startmask, endmask, nlwMiddle); + + for (d = 0; d < depthDst; d++, saveP += sizeDst, psrc += tileHeight) { /* @@@ NEXT PLANE @@@ */ + if (!(planemask & (1 << d))) + continue; + + p = saveP; + h = saveH; + iy = saveIY; + nlwExtra = nlwidth - nlwMiddle; + + if (startmask && endmask) { + nlwExtra -= 1; + while (h--) { + srcpix = psrc[iy]; + iy++; + if (iy == tileHeight) + iy = 0; + nlw = nlwMiddle; + *p = MROP_MASK (srcpix,*p,startmask); + p++; + while (nlw--) { + *p = MROP_SOLID(srcpix,*p); + p++; + } + + *p = MROP_MASK(srcpix,*p,endmask); + afbScanlineInc(p, nlwExtra); + } + } else if (startmask && !endmask) { + nlwExtra -= 1; + while (h--) { + srcpix = psrc[iy]; + iy++; + if (iy == tileHeight) + iy = 0; + nlw = nlwMiddle; + *p = MROP_MASK(srcpix,*p,startmask); + p++; + while (nlw--) { + *p = MROP_SOLID(srcpix,*p); + p++; + } + afbScanlineInc(p, nlwExtra); + } + } else if (!startmask && endmask) { + while (h--) { + srcpix = psrc[iy]; + iy++; + if (iy == tileHeight) + iy = 0; + nlw = nlwMiddle; + while (nlw--) { + *p = MROP_SOLID(srcpix,*p); + p++; + } + + *p = MROP_MASK(srcpix,*p,endmask); + afbScanlineInc(p, nlwExtra); + } + } else { /* no ragged bits at either end */ + while (h--) { + srcpix = psrc[iy]; + iy++; + if (iy == tileHeight) + iy = 0; + nlw = nlwMiddle; + while (nlw--) { + *p = MROP_SOLID (srcpix,*p); + p++; + } + afbScanlineInc(p, nlwExtra); + } + } + } /* for (d = ...) */ + } + pbox++; + } +} + +void +MROP_NAME(afbTileArea)(pDraw, nbox, pbox, alu, pTile, xOff, yOff, planemask) + DrawablePtr pDraw; + int nbox; + BoxPtr pbox; + int alu; + PixmapPtr pTile; + int xOff; + int yOff; + unsigned long planemask; +{ + register PixelType *psrc; + /* pointer to bits in tile, if needed */ + int nlwidth; /* width in longwords of the drawable */ + MROP_DECLARE_REG () + register int h; /* height of current box */ + register PixelType *pdst; /* pointer to bits we're writing */ + register PixelType tmpsrc; +#if (MROP) != Mcopy + register PixelType tmpdst; +#endif + int sizeDst; + int depthDst; + int sizeTile; + int tileLine; + int iline; + int w, width, x, xSrc, ySrc, srcStartOver, nend; + int tlwidth, rem, tileWidth, tileHeight, endinc; + int saveW; + PixelType *psrcT; + int d; + int nstart; + PixelType startmask; + PixelType endmask; /* masks for reggedy bits at either end of line */ + int nlMiddle; /* number of longwords between sides of boxes */ + int iy; + PixelType *pBase; /* pointer to start of drawable */ + PixelType *saveP; + PixelType *pStartDst; + PixelType *pStartTile; + int saveH; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + pBase); + + MROP_INITIALIZE(alu,~0) + + tileHeight = pTile->drawable.height; + tileWidth = pTile->drawable.width; + tlwidth = pTile->devKind / sizeof (PixelType); + sizeTile = tlwidth * tileHeight; + + xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth); + ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight); + + while (nbox--) { + saveW = pbox->x2 - pbox->x1; + iline = (pbox->y1 - ySrc) % tileHeight; + psrcT = (PixelType *) pTile->devPrivate.ptr; + tileLine = iline * tlwidth; + saveH = pbox->y2 - pbox->y1; + saveP = afbScanline(pBase, pbox->x1, pbox->y1, nlwidth); + + for (d = 0; d < depthDst; d++, psrcT += sizeTile, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */ + if (!(planemask & (1 << d))) + continue; + + h = saveH; + pStartDst = saveP; + pStartTile = psrcT + tileLine; + iy = iline; + + while (h--) { + x = pbox->x1; + width = saveW; + pdst = pStartDst; + while(width > 0) { + psrc = pStartTile; + w = min(tileWidth, width); + if((rem = (x - xSrc) % tileWidth) != 0) { + /* if we're in the middle of the tile, get + as many bits as will finish the span, or + as many as will get to the left edge of the tile, + or a longword worth, starting at the appropriate + offset in the tile. + */ + w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD); + endinc = rem / BITMAP_SCANLINE_PAD; + + getbits ((psrc+endinc), (rem&PIM), w, tmpsrc); +#if (MROP) != Mcopy + getbits (pdst, (x & PIM), w, tmpdst); + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + putbits (tmpsrc, (x & PIM), w, pdst); + + if((x & PIM) + w >= PPW) + pdst++; + } else if(((x & PIM) + w) < PPW) { + /* doing < PPW bits is easy, and worth special-casing */ + tmpsrc = *psrc; +#if (MROP) != Mcopy + getbits (pdst, (x & PIM), w, tmpdst); + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + putbits (tmpsrc, (x & PIM), w, pdst); + } else { + /* start at the left edge of the tile, + and put down as much as we can + */ + maskbits(x, w, startmask, endmask, nlMiddle); + + if (startmask) + nstart = PPW - (x & PIM); + else + nstart = 0; + if (endmask) + nend = (x + w) & PIM; + else + nend = 0; + + srcStartOver = nstart > PLST; + + if(startmask) { + tmpsrc = *psrc; +#if (MROP) != Mcopy + getbits (pdst, (x & PIM), nstart, tmpdst); + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + putbits (tmpsrc, (x & PIM), nstart, pdst); + pdst++; + if(srcStartOver) + psrc++; + } + + while(nlMiddle--) { + getbits (psrc, nstart, PPW, tmpsrc); +#if (MROP) != Mcopy + tmpdst = *pdst; + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + *pdst++ = tmpsrc; + /*putbits (tmpsrc, 0, PPW, pdst); + pdst++;*/ + psrc++; + } + + if(endmask) { + getbits (psrc, nstart, nend, tmpsrc); +#if (MROP) != Mcopy + tmpdst = *pdst; + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + putbits (tmpsrc, 0, nend, pdst); + } + } + x += w; + width -= w; + } /* while (width > 0) */ + + pStartDst += nlwidth; + if (++iy >= tileHeight) { + iy = 0; + pStartTile = psrcT; + } else + pStartTile += tlwidth; + + } /* while (h) */ + } /* for (d = ... ) */ + pbox++; + } /* for each box */ +} + +void +MROP_NAME(afbOpaqueStippleAreaPPW)(pDraw, nbox, pbox, alu, ptile, + rropsOS, planemask) + DrawablePtr pDraw; + int nbox; + BoxPtr pbox; + int alu; + PixmapPtr ptile; + register unsigned char *rropsOS; + unsigned long planemask; +{ + register PixelType *psrc; + /* pointer to bits in tile, if needed */ + int tileHeight; /* height of the tile */ + register PixelType srcpix = 0; + int nlwidth; /* width in longwords of the drawable */ + int w; /* width of current box */ + MROP_DECLARE_REG () + register int h; /* height of current box */ + register int nlw; /* loop version of nlwMiddle */ + register PixelType *p; /* pointer to bits we're writing */ + int sizeDst; + int depthDst; + register int d; + PixelType startmask; + PixelType endmask; /* masks for reggedy bits at either end of line */ + int nlwMiddle; /* number of longwords between sides of boxes */ + int nlwExtra; /* to get from right of box to left of next span */ + register int iy; /* index of current scanline in tile */ + PixelType *pbits; /* pointer to start of drawable */ + PixelType *saveP; + int saveH; + int saveIY; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + pbits); + + MROP_INITIALIZE(alu,~0) + + tileHeight = ptile->drawable.height; + psrc = (PixelType *)(ptile->devPrivate.ptr); + + while (nbox--) { + w = pbox->x2 - pbox->x1; + saveH = pbox->y2 - pbox->y1; + saveIY = pbox->y1 % tileHeight; + saveP = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth); + + if ( ((pbox->x1 & PIM) + w) < PPW) { + maskpartialbits(pbox->x1, w, startmask); + nlwExtra = nlwidth; + for (d = 0; d < depthDst; d++, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */ + if (!(planemask & (1 << d))) + continue; + + p = saveP; + h = saveH; + iy = saveIY; + + while (h--) { + switch (rropsOS[d]) { + case RROP_BLACK: + srcpix = 0; + break; + case RROP_WHITE: + srcpix = ~0; + break; + case RROP_COPY: + srcpix = psrc[iy]; + break; + case RROP_INVERT: + srcpix = ~psrc[iy]; + break; + } + iy++; + if (iy == tileHeight) + iy = 0; + *p = MROP_MASK(srcpix,*p,startmask); + afbScanlineInc(p, nlwExtra); + } + } + } else { + maskbits(pbox->x1, w, startmask, endmask, nlwMiddle); + + for (d = 0; d < depthDst; d++, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */ + if (!(planemask & (1 << d))) + continue; + + p = saveP; + h = saveH; + iy = saveIY; + nlwExtra = nlwidth - nlwMiddle; + + if (startmask && endmask) { + nlwExtra -= 1; + while (h--) { + switch (rropsOS[d]) { + case RROP_BLACK: + srcpix = 0; + break; + case RROP_WHITE: + srcpix = ~0; + break; + case RROP_COPY: + srcpix = psrc[iy]; + break; + case RROP_INVERT: + srcpix = ~psrc[iy]; + break; + } + iy++; + if (iy == tileHeight) + iy = 0; + nlw = nlwMiddle; + *p = MROP_MASK (srcpix,*p,startmask); + p++; + while (nlw--) { + *p = MROP_SOLID(srcpix,*p); + p++; + } + + *p = MROP_MASK(srcpix,*p,endmask); + afbScanlineInc(p, nlwExtra); + } + } else if (startmask && !endmask) { + nlwExtra -= 1; + while (h--) { + switch (rropsOS[d]) { + case RROP_BLACK: + srcpix = 0; + break; + case RROP_WHITE: + srcpix = ~0; + break; + case RROP_COPY: + srcpix = psrc[iy]; + break; + case RROP_INVERT: + srcpix = ~psrc[iy]; + break; + } + iy++; + if (iy == tileHeight) + iy = 0; + nlw = nlwMiddle; + *p = MROP_MASK(srcpix,*p,startmask); + p++; + while (nlw--) { + *p = MROP_SOLID(srcpix,*p); + p++; + } + afbScanlineInc(p, nlwExtra); + } + } else if (!startmask && endmask) { + while (h--) { + switch (rropsOS[d]) { + case RROP_BLACK: + srcpix = 0; + break; + case RROP_WHITE: + srcpix = ~0; + break; + case RROP_COPY: + srcpix = psrc[iy]; + break; + case RROP_INVERT: + srcpix = ~psrc[iy]; + break; + } + iy++; + if (iy == tileHeight) + iy = 0; + nlw = nlwMiddle; + while (nlw--) { + *p = MROP_SOLID(srcpix,*p); + p++; + } + + *p = MROP_MASK(srcpix,*p,endmask); + afbScanlineInc(p, nlwExtra); + } + } else { /* no ragged bits at either end */ + while (h--) { + switch (rropsOS[d]) { + case RROP_BLACK: + srcpix = 0; + break; + case RROP_WHITE: + srcpix = ~0; + break; + case RROP_COPY: + srcpix = psrc[iy]; + break; + case RROP_INVERT: + srcpix = ~psrc[iy]; + break; + } + iy++; + if (iy == tileHeight) + iy = 0; + nlw = nlwMiddle; + while (nlw--) { + *p = MROP_SOLID (srcpix,*p); + p++; + } + afbScanlineInc(p, nlwExtra); + } + } + } /* for (d = ...) */ + } + pbox++; + } +} + +void +MROP_NAME(afbOpaqueStippleArea)(pDraw, nbox, pbox, alu, pTile, xOff, yOff, + rropsOS, planemask) + DrawablePtr pDraw; + int nbox; + BoxPtr pbox; + int alu; + PixmapPtr pTile; + int xOff; + int yOff; + register unsigned char *rropsOS; + unsigned long planemask; +{ + register PixelType *psrc; + /* pointer to bits in tile, if needed */ + int nlwidth; /* width in longwords of the drawable */ + MROP_DECLARE_REG () + register int h; /* height of current box */ + register PixelType *pdst; /* pointer to bits we're writing */ + register PixelType tmpsrc = 0; +#if (MROP) != Mcopy + register PixelType tmpdst; +#endif + int sizeDst; + int depthDst; + int tileLine; + int iline; + int w, width, x, xSrc, ySrc, srcStartOver, nend; + int tlwidth, rem, tileWidth, tileHeight, endinc; + int saveW; + PixelType *psrcT; + int d; + int nstart; + PixelType startmask; + PixelType endmask; /* masks for reggedy bits at either end of line */ + int nlMiddle; /* number of longwords between sides of boxes */ + int iy; + PixelType *pBase; /* pointer to start of drawable */ + PixelType *saveP; + PixelType *pStartDst; + PixelType *pStartTile; + int saveH; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + pBase); + + MROP_INITIALIZE(alu,~0) + + tileHeight = pTile->drawable.height; + tileWidth = pTile->drawable.width; + tlwidth = pTile->devKind / sizeof (PixelType); + + xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth); + ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight); + + while (nbox--) { + saveW = pbox->x2 - pbox->x1; + iline = (pbox->y1 - ySrc) % tileHeight; + psrcT = (PixelType *) pTile->devPrivate.ptr; + tileLine = iline * tlwidth; + saveH = pbox->y2 - pbox->y1; + saveP = afbScanline(pBase, pbox->x1, pbox->y1, nlwidth); + + for (d = 0; d < depthDst; d++, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */ + if (!(planemask & (1 << d))) + continue; + + h = saveH; + pStartDst = saveP; + pStartTile = psrcT + tileLine; + iy = iline; + + while (h--) { + x = pbox->x1; + width = saveW; + pdst = pStartDst; + while(width > 0) { + psrc = pStartTile; + w = min(tileWidth, width); + if((rem = (x - xSrc) % tileWidth) != 0) { + /* if we're in the middle of the tile, get + as many bits as will finish the span, or + as many as will get to the left edge of the tile, + or a longword worth, starting at the appropriate + offset in the tile. + */ + w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD); + endinc = rem / BITMAP_SCANLINE_PAD; + + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + + case RROP_COPY: + getbits ((psrc+endinc), (rem&PIM), w, tmpsrc); + break; + + case RROP_INVERT: + getbits ((psrc+endinc), (rem&PIM), w, tmpsrc); + tmpsrc = ~tmpsrc; + break; + } +#if (MROP) != Mcopy + getbits (pdst, (x & PIM), w, tmpdst); + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + putbits (tmpsrc, (x & PIM), w, pdst); + + if((x & PIM) + w >= PPW) + pdst++; + } else if(((x & PIM) + w) < PPW) { + /* doing < PPW bits is easy, and worth special-casing */ + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + case RROP_COPY: + tmpsrc = *psrc; + break; + case RROP_INVERT: + tmpsrc = ~*psrc; + break; + } +#if (MROP) != Mcopy + getbits (pdst, (x & PIM), w, tmpdst); + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + putbits (tmpsrc, (x & PIM), w, pdst); + } else { + /* start at the left edge of the tile, + and put down as much as we can + */ + maskbits(x, w, startmask, endmask, nlMiddle); + + if (startmask) + nstart = PPW - (x & PIM); + else + nstart = 0; + if (endmask) + nend = (x + w) & PIM; + else + nend = 0; + + srcStartOver = nstart > PLST; + + if(startmask) { + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + case RROP_COPY: + tmpsrc = *psrc; + break; + case RROP_INVERT: + tmpsrc = ~*psrc; + break; + } +#if (MROP) != Mcopy + getbits (pdst, (x & PIM), nstart, tmpdst); + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + putbits (tmpsrc, (x & PIM), nstart, pdst); + pdst++; + if(srcStartOver) + psrc++; + } + + while(nlMiddle--) { + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + case RROP_COPY: + getbits (psrc, nstart, PPW, tmpsrc); + break; + case RROP_INVERT: + getbits (psrc, nstart, PPW, tmpsrc); + tmpsrc = ~tmpsrc; + break; + } +#if (MROP) != Mcopy + tmpdst = *pdst; + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + *pdst++ = tmpsrc; + /*putbits (tmpsrc, 0, PPW, pdst); + pdst++; */ + psrc++; + } + + if(endmask) { + switch (rropsOS[d]) { + case RROP_BLACK: + tmpsrc = 0; + break; + case RROP_WHITE: + tmpsrc = ~0; + break; + + case RROP_COPY: + getbits (psrc, nstart, nend, tmpsrc); + break; + + case RROP_INVERT: + getbits (psrc, nstart, nend, tmpsrc); + tmpsrc = ~tmpsrc; + break; + } +#if (MROP) != Mcopy + tmpdst = *pdst; + tmpsrc = DoMergeRop (tmpsrc, tmpdst); +#endif + putbits (tmpsrc, 0, nend, pdst); + } + } + x += w; + width -= w; + } /* while (width > 0) */ + + pStartDst += nlwidth; + if (++iy >= tileHeight) { + iy = 0; + pStartTile = psrcT; + } else + pStartTile += tlwidth; + + } /* while (h) */ + } /* for (d = ... ) */ + pbox++; + } /* for each box */ +} diff --git a/afb/afbwindow.c b/afb/afbwindow.c new file mode 100644 index 000000000..40597c72a --- /dev/null +++ b/afb/afbwindow.c @@ -0,0 +1,316 @@ +/* $XFree86: xc/programs/Xserver/afb/afbwindow.c,v 3.0 1996/08/18 01:45:58 dawes Exp $ */ +/* $XConsortium: afbwindow.c,v 5.14 94/04/17 20:28:36 dpw Exp $ */ +/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */ +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#include "X.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "afb.h" +#include "mistruct.h" +#include "regionstr.h" +#include "maskbits.h" + +extern WindowPtr *WindowTable; + +Bool +afbCreateWindow(pWin) + register WindowPtr pWin; +{ + register afbPrivWin *pPrivWin; + + pPrivWin = (afbPrivWin *)(pWin->devPrivates[afbWindowPrivateIndex].ptr); + pPrivWin->pRotatedBorder = NullPixmap; + pPrivWin->pRotatedBackground = NullPixmap; + pPrivWin->fastBackground = FALSE; + pPrivWin->fastBorder = FALSE; +#ifdef PIXMAP_PER_WINDOW + pWin->devPrivates[frameWindowPrivateIndex].ptr = + pWin->pDrawable.pScreen->devPrivates[afbScreenPrivateIndex].ptr; +#endif + + return (TRUE); +} + +/* This always returns true, because Xfree can't fail. It might be possible + * on some devices for Destroy to fail */ +Bool +afbDestroyWindow(pWin) + WindowPtr pWin; +{ + register afbPrivWin *pPrivWin; + + pPrivWin = (afbPrivWin *)(pWin->devPrivates[afbWindowPrivateIndex].ptr); + + if (pPrivWin->pRotatedBorder) + (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBorder); + if (pPrivWin->pRotatedBackground) + (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBackground); + + return (TRUE); +} + +/*ARGSUSED*/ +Bool +afbMapWindow(pWindow) + WindowPtr pWindow; +{ + return (TRUE); +} + +/* (x, y) is the upper left corner of the window on the screen + do we really need to pass this? (is it a;ready in pWin->absCorner?) + we only do the rotation for pixmaps that are 32 bits wide (padded +or otherwise.) + afbChangeWindowAttributes() has already put a copy of the pixmap +in pPrivWin->pRotated* +*/ + +/*ARGSUSED*/ +Bool +afbPositionWindow(pWin, x, y) + WindowPtr pWin; + int x, y; +{ + register afbPrivWin *pPrivWin; + int reset = 0; + + pPrivWin = (afbPrivWin *)(pWin->devPrivates[afbWindowPrivateIndex].ptr); + if (pWin->backgroundState == BackgroundPixmap && pPrivWin->fastBackground) { + afbXRotatePixmap(pPrivWin->pRotatedBackground, + pWin->drawable.x - pPrivWin->oldRotate.x); + afbYRotatePixmap(pPrivWin->pRotatedBackground, + pWin->drawable.y - pPrivWin->oldRotate.y); + reset = 1; + } + + if (!pWin->borderIsPixel && pPrivWin->fastBorder) { + while (pWin->backgroundState == ParentRelative) + pWin = pWin->parent; + afbXRotatePixmap(pPrivWin->pRotatedBorder, + pWin->drawable.x - pPrivWin->oldRotate.x); + afbYRotatePixmap(pPrivWin->pRotatedBorder, + pWin->drawable.y - pPrivWin->oldRotate.y); + reset = 1; + } + if (reset) { + pPrivWin->oldRotate.x = pWin->drawable.x; + pPrivWin->oldRotate.y = pWin->drawable.y; + } + + /* This is the "wrong" fix to the right problem, but it doesn't really + * cost very much. When the window is moved, we need to invalidate any + * RotatedPixmap that exists in any GC currently validated against this + * window. + */ + pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; + + /* Again, we have no failure modes indicated by any of the routines + * we've called, so we have to assume it worked */ + return (TRUE); +} + +/*ARGSUSED*/ +Bool +afbUnmapWindow(pWindow) + WindowPtr pWindow; +{ + return (TRUE); +} + +/* UNCLEAN! + this code calls the bitblt helper code directly. + + afbCopyWindow copies only the parts of the destination that are +visible in the source. +*/ + + +void +afbCopyWindow(pWin, ptOldOrg, prgnSrc) + WindowPtr pWin; + DDXPointRec ptOldOrg; + RegionPtr prgnSrc; +{ + DDXPointPtr pptSrc; + register DDXPointPtr ppt; + RegionPtr prgnDst; + register BoxPtr pbox; + register int dx, dy; + register int i, nbox; + WindowPtr pwinRoot; + + pwinRoot = WindowTable[pWin->drawable.pScreen->myNum]; + + prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1); + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); + REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip, + prgnSrc); + + pbox = REGION_RECTS(prgnDst); + nbox = REGION_NUM_RECTS(prgnDst); + if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) + return; + ppt = pptSrc; + + for (i=nbox; --i >= 0; ppt++, pbox++) { + ppt->x = pbox->x1 + dx; + ppt->y = pbox->y1 + dy; + } + + afbDoBitblt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot, GXcopy, prgnDst, + pptSrc, ~0); + DEALLOCATE_LOCAL(pptSrc); + REGION_DESTROY(pWin->drawable.pScreen, prgnDst); +} + + + +/* swap in correct PaintWindow* routine. If we can use a fast output +routine (i.e. the pixmap is paddable to 32 bits), also pre-rotate a copy +of it in devPrivate. +*/ +Bool +afbChangeWindowAttributes(pWin, mask) + register WindowPtr pWin; + register unsigned long mask; +{ + register unsigned long index; + register afbPrivWin *pPrivWin; + WindowPtr pBgWin; + + pPrivWin = (afbPrivWin *)(pWin->devPrivates[afbWindowPrivateIndex].ptr); + /* + * When background state changes from ParentRelative and + * we had previously rotated the fast border pixmap to match + * the parent relative origin, rerotate to match window + */ + if (mask & (CWBackPixmap | CWBackPixel) && + pWin->backgroundState != ParentRelative && pPrivWin->fastBorder && + (pPrivWin->oldRotate.x != pWin->drawable.x || + pPrivWin->oldRotate.y != pWin->drawable.y)) { + afbXRotatePixmap(pPrivWin->pRotatedBorder, + pWin->drawable.x - pPrivWin->oldRotate.x); + afbYRotatePixmap(pPrivWin->pRotatedBorder, + pWin->drawable.y - pPrivWin->oldRotate.y); + pPrivWin->oldRotate.x = pWin->drawable.x; + pPrivWin->oldRotate.y = pWin->drawable.y; + } + while(mask) { + index = lowbit (mask); + mask &= ~index; + switch(index) { + case CWBackPixmap: + if (pWin->backgroundState == None) + pPrivWin->fastBackground = FALSE; + else if (pWin->backgroundState == ParentRelative) { + pPrivWin->fastBackground = FALSE; + /* Rotate border to match parent origin */ + if (pPrivWin->pRotatedBorder) { + for (pBgWin = pWin->parent; + pBgWin->backgroundState == ParentRelative; + pBgWin = pBgWin->parent); + afbXRotatePixmap(pPrivWin->pRotatedBorder, + pBgWin->drawable.x - pPrivWin->oldRotate.x); + afbYRotatePixmap(pPrivWin->pRotatedBorder, + pBgWin->drawable.y - pPrivWin->oldRotate.y); + pPrivWin->oldRotate.x = pBgWin->drawable.x; + pPrivWin->oldRotate.y = pBgWin->drawable.y; + } + } else if ((pWin->background.pixmap->drawable.width <= PPW) && + !(pWin->background.pixmap->drawable.width & + (pWin->background.pixmap->drawable.width - 1))) { + afbCopyRotatePixmap(pWin->background.pixmap, + &pPrivWin->pRotatedBackground, + pWin->drawable.x, pWin->drawable.y); + if (pPrivWin->pRotatedBackground) { + pPrivWin->fastBackground = TRUE; + pPrivWin->oldRotate.x = pWin->drawable.x; + pPrivWin->oldRotate.y = pWin->drawable.y; + } else + pPrivWin->fastBackground = FALSE; + } else + pPrivWin->fastBackground = FALSE; + break; + + case CWBackPixel: + pPrivWin->fastBackground = FALSE; + break; + + case CWBorderPixmap: + if ((pWin->border.pixmap->drawable.width <= PPW) && + !(pWin->border.pixmap->drawable.width & + (pWin->border.pixmap->drawable.width - 1))) { + for (pBgWin = pWin; + pBgWin->backgroundState == ParentRelative; + pBgWin = pBgWin->parent); + afbCopyRotatePixmap(pWin->border.pixmap, + &pPrivWin->pRotatedBorder, + pBgWin->drawable.x, pBgWin->drawable.y); + if (pPrivWin->pRotatedBorder) { + pPrivWin->fastBorder = TRUE; + pPrivWin->oldRotate.x = pBgWin->drawable.x; + pPrivWin->oldRotate.y = pBgWin->drawable.y; + } else + pPrivWin->fastBorder = FALSE; + } else + pPrivWin->fastBorder = FALSE; + break; + case CWBorderPixel: + pPrivWin->fastBorder = FALSE; + break; + } + } + /* Again, we have no failure modes indicated by any of the routines + * we've called, so we have to assume it worked */ + return (TRUE); +} diff --git a/afb/afbzerarc.c b/afb/afbzerarc.c new file mode 100644 index 000000000..334a79011 --- /dev/null +++ b/afb/afbzerarc.c @@ -0,0 +1,206 @@ +/* $XFree86: xc/programs/Xserver/afb/afbzerarc.c,v 3.2 2001/10/28 03:32:59 tsi Exp $ */ +/************************************************************ + +Copyright (c) 1989 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +********************************************************/ + +/* $XConsortium: afbzerarc.c,v 5.19 94/04/17 20:28:37 dpw Exp $ */ + +/* Derived from: + * "Algorithm for drawing ellipses or hyperbolae with a digital plotter" + * by M. L. V. Pitteway + * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289 + */ + +#include "X.h" +#include "Xprotostr.h" +#include "miscstruct.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "afb.h" +#include "maskbits.h" +#include "mizerarc.h" +#include "mi.h" + +/* + * Note: LEFTMOST must be the bit leftmost in the actual screen + * representation. This depends also on the IMAGE_BYTE_ORDER. + * LONG2CHARS() takes care of the re-ordering as required. (DHD) + */ +#if (BITMAP_BIT_ORDER == MSBFirst) +#define LEFTMOST ((PixelType) LONG2CHARS((1 << PLST))) +#else +#define LEFTMOST ((PixelType) LONG2CHARS(1)) +#endif + +#define Pixelate(base,yoff,xoff) \ +{ \ + paddr = afbScanlineOffset(base, (yoff) + ((xoff)>>PWSH)); \ + pmask = SCRRIGHT(LEFTMOST, (xoff) & PIM); \ + for (de = 0; de < depthDst; de++, paddr += sizeDst) /* @@@ NEXT PLANE @@@ */ \ + switch (rrops[de]) { \ + case RROP_BLACK: \ + *paddr &= ~pmask; \ + break; \ + case RROP_WHITE: \ + *paddr |= pmask; \ + break; \ + case RROP_INVERT: \ + *paddr ^= pmask; \ + break; \ + case RROP_NOP: \ + break; \ + } \ +} + +#define DoPix(bit,base,yoff,xoff) if (mask & bit) Pixelate(base,yoff,xoff); + +static void +afbZeroArcSS(pDraw, pGC, arc) + DrawablePtr pDraw; + GCPtr pGC; + xArc *arc; +{ + miZeroArcRec info; + Bool do360; + register int de; + register int x, y, a, b, d, mask; + register int k1, k3, dx, dy; + PixelType *addrl; + PixelType *yorgl, *yorgol; + int nlwidth, yoffset, dyoffset; + int sizeDst, depthDst; + PixelType pmask; + register PixelType *paddr; + register unsigned char *rrops; + + rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops; + + afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst, + addrl); + do360 = miZeroArcSetup(arc, &info, TRUE); + yorgl = addrl + ((info.yorg + pDraw->y) * nlwidth); + yorgol = addrl + ((info.yorgo + pDraw->y) * nlwidth); + info.xorg += pDraw->x; + info.xorgo += pDraw->x; + MIARCSETUP(); + yoffset = y ? nlwidth : 0; + dyoffset = 0; + mask = info.initialMask; + if (!(arc->width & 1)) { + DoPix(2, yorgl, 0, info.xorgo); + DoPix(8, yorgol, 0, info.xorgo); + } + if (!info.end.x || !info.end.y) { + mask = info.end.mask; + info.end = info.altend; + } + if (do360 && (arc->width == arc->height) && !(arc->width & 1)) { + int xoffset = nlwidth; + PixelType *yorghl = afbScanlineDeltaNoBankSwitch(yorgl, info.h, nlwidth); + int xorghp = info.xorg + info.h; + int xorghn = info.xorg - info.h; + + while (1) { + Pixelate(yorgl, yoffset, info.xorg + x); + Pixelate(yorgl, yoffset, info.xorg - x); + Pixelate(yorgol, -yoffset, info.xorg - x); + Pixelate(yorgol, -yoffset, info.xorg + x); + if (a < 0) + break; + Pixelate(yorghl, -xoffset, xorghp - y); + Pixelate(yorghl, -xoffset, xorghn + y); + Pixelate(yorghl, xoffset, xorghn + y); + Pixelate(yorghl, xoffset, xorghp - y); + xoffset += nlwidth; + MIARCCIRCLESTEP(yoffset += nlwidth;); + } + x = info.w; + yoffset = info.h * nlwidth; + } else if (do360) { + while (y < info.h || x < info.w) { + MIARCOCTANTSHIFT(dyoffset = nlwidth;); + Pixelate(yorgl, yoffset, info.xorg + x); + Pixelate(yorgl, yoffset, info.xorgo - x); + Pixelate(yorgol, -yoffset, info.xorgo - x); + Pixelate(yorgol, -yoffset, info.xorg + x); + MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;); + } + } else { + while (y < info.h || x < info.w) { + MIARCOCTANTSHIFT(dyoffset = nlwidth;); + if ((x == info.start.x) || (y == info.start.y)) { + mask = info.start.mask; + info.start = info.altstart; + } + DoPix(1, yorgl, yoffset, info.xorg + x); + DoPix(2, yorgl, yoffset, info.xorgo - x); + DoPix(4, yorgol, -yoffset, info.xorgo - x); + DoPix(8, yorgol, -yoffset, info.xorg + x); + if ((x == info.end.x) || (y == info.end.y)) { + mask = info.end.mask; + info.end = info.altend; + } + MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;); + } + } + if ((x == info.start.x) || (y == info.start.y)) + mask = info.start.mask; + DoPix(1, yorgl, yoffset, info.xorg + x); + DoPix(4, yorgol, -yoffset, info.xorgo - x); + if (arc->height & 1) { + DoPix(2, yorgl, yoffset, info.xorgo - x); + DoPix(8, yorgol, -yoffset, info.xorg + x); + } +} + +void +afbZeroPolyArcSS(pDraw, pGC, narcs, parcs) + DrawablePtr pDraw; + GCPtr pGC; + int narcs; + xArc *parcs; +{ + register xArc *arc; + register int i; + BoxRec box; + RegionPtr cclip; + + cclip = pGC->pCompositeClip; + for (arc = parcs, i = narcs; --i >= 0; arc++) { + if (miCanZeroArc(arc)) { + box.x1 = arc->x + pDraw->x; + box.y1 = arc->y + pDraw->y; + box.x2 = box.x1 + (int)arc->width + 1; + box.y2 = box.y1 + (int)arc->height + 1; + if (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) + afbZeroArcSS(pDraw, pGC, arc); + else + miZeroPolyArc(pDraw, pGC, 1, arc); + } else + miPolyArc(pDraw, pGC, 1, arc); + } +} |