|
Carlos Lopez |
a09598 |
/*
|
|
Carlos Lopez |
a09598 |
* Graphics Context support for Mac OS X rootless X server
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
/*
|
|
Carlos Lopez |
a09598 |
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
|
|
Carlos Lopez |
a09598 |
* Copyright (c) 2002 Torrey T. Lyons. All Rights Reserved.
|
|
Carlos Lopez |
a09598 |
* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
|
|
Carlos Lopez |
a09598 |
*
|
|
Carlos Lopez |
a09598 |
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
Carlos Lopez |
a09598 |
* copy of this software and associated documentation files (the "Software"),
|
|
Carlos Lopez |
a09598 |
* to deal in the Software without restriction, including without limitation
|
|
Carlos Lopez |
a09598 |
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
Carlos Lopez |
a09598 |
* and/or sell copies of the Software, and to permit persons to whom the
|
|
Carlos Lopez |
a09598 |
* Software is furnished to do so, subject to the following conditions:
|
|
Carlos Lopez |
a09598 |
*
|
|
Carlos Lopez |
a09598 |
* The above copyright notice and this permission notice shall be included in
|
|
Carlos Lopez |
a09598 |
* all copies or substantial portions of the Software.
|
|
Carlos Lopez |
a09598 |
*
|
|
Carlos Lopez |
a09598 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
Carlos Lopez |
a09598 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
Carlos Lopez |
a09598 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
Carlos Lopez |
a09598 |
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
Carlos Lopez |
a09598 |
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
Carlos Lopez |
a09598 |
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
Carlos Lopez |
a09598 |
* DEALINGS IN THE SOFTWARE.
|
|
Carlos Lopez |
a09598 |
*
|
|
Carlos Lopez |
a09598 |
* Except as contained in this notice, the name(s) of the above copyright
|
|
Carlos Lopez |
a09598 |
* holders shall not be used in advertising or otherwise to promote the sale,
|
|
Carlos Lopez |
a09598 |
* use or other dealings in this Software without prior written authorization.
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/rootlessGC.c,v 1.3 2002/07/24 05:58:33 torrey Exp $ */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include "mi.h"
|
|
Carlos Lopez |
a09598 |
#include "scrnintstr.h"
|
|
Carlos Lopez |
a09598 |
#include "gcstruct.h"
|
|
Carlos Lopez |
a09598 |
#include "pixmapstr.h"
|
|
Carlos Lopez |
a09598 |
#include "windowstr.h"
|
|
Carlos Lopez |
a09598 |
#include "dixfontstr.h"
|
|
Carlos Lopez |
a09598 |
#include "mivalidate.h"
|
|
Carlos Lopez |
a09598 |
#include "fb.h"
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include <sys types.h=""></sys>
|
|
Carlos Lopez |
a09598 |
#include <sys stat.h=""></sys>
|
|
Carlos Lopez |
a09598 |
#include <fcntl.h></fcntl.h>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include "rootless-common.h"
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// GC functions
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
RootlessValidateGC(GCPtr pGC, unsigned long changes,
|
|
Carlos Lopez |
a09598 |
DrawablePtr pDrawable);
|
|
Carlos Lopez |
a09598 |
static void RootlessChangeGC(GCPtr pGC, unsigned long mask);
|
|
Carlos Lopez |
a09598 |
static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
|
|
Carlos Lopez |
a09598 |
static void RootlessDestroyGC(GCPtr pGC);
|
|
Carlos Lopez |
a09598 |
static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue,
|
|
Carlos Lopez |
a09598 |
int nrects);
|
|
Carlos Lopez |
a09598 |
static void RootlessDestroyClip(GCPtr pGC);
|
|
Carlos Lopez |
a09598 |
static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCFuncs rootlessGCFuncs = {
|
|
Carlos Lopez |
a09598 |
RootlessValidateGC,
|
|
Carlos Lopez |
a09598 |
RootlessChangeGC,
|
|
Carlos Lopez |
a09598 |
RootlessCopyGC,
|
|
Carlos Lopez |
a09598 |
RootlessDestroyGC,
|
|
Carlos Lopez |
a09598 |
RootlessChangeClip,
|
|
Carlos Lopez |
a09598 |
RootlessDestroyClip,
|
|
Carlos Lopez |
a09598 |
RootlessCopyClip,
|
|
Carlos Lopez |
a09598 |
};
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// GC operations
|
|
Carlos Lopez |
a09598 |
static void RootlessFillSpans();
|
|
Carlos Lopez |
a09598 |
static void RootlessSetSpans();
|
|
Carlos Lopez |
a09598 |
static void RootlessPutImage();
|
|
Carlos Lopez |
a09598 |
static RegionPtr RootlessCopyArea();
|
|
Carlos Lopez |
a09598 |
static RegionPtr RootlessCopyPlane();
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyPoint();
|
|
Carlos Lopez |
a09598 |
static void RootlessPolylines();
|
|
Carlos Lopez |
a09598 |
static void RootlessPolySegment();
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyRectangle();
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyArc();
|
|
Carlos Lopez |
a09598 |
static void RootlessFillPolygon();
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyFillRect();
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyFillArc();
|
|
Carlos Lopez |
a09598 |
static int RootlessPolyText8();
|
|
Carlos Lopez |
a09598 |
static int RootlessPolyText16();
|
|
Carlos Lopez |
a09598 |
static void RootlessImageText8();
|
|
Carlos Lopez |
a09598 |
static void RootlessImageText16();
|
|
Carlos Lopez |
a09598 |
static void RootlessImageGlyphBlt();
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyGlyphBlt();
|
|
Carlos Lopez |
a09598 |
static void RootlessPushPixels();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static GCOps rootlessGCOps = {
|
|
Carlos Lopez |
a09598 |
RootlessFillSpans,
|
|
Carlos Lopez |
a09598 |
RootlessSetSpans,
|
|
Carlos Lopez |
a09598 |
RootlessPutImage,
|
|
Carlos Lopez |
a09598 |
RootlessCopyArea,
|
|
Carlos Lopez |
a09598 |
RootlessCopyPlane,
|
|
Carlos Lopez |
a09598 |
RootlessPolyPoint,
|
|
Carlos Lopez |
a09598 |
RootlessPolylines,
|
|
Carlos Lopez |
a09598 |
RootlessPolySegment,
|
|
Carlos Lopez |
a09598 |
RootlessPolyRectangle,
|
|
Carlos Lopez |
a09598 |
RootlessPolyArc,
|
|
Carlos Lopez |
a09598 |
RootlessFillPolygon,
|
|
Carlos Lopez |
a09598 |
RootlessPolyFillRect,
|
|
Carlos Lopez |
a09598 |
RootlessPolyFillArc,
|
|
Carlos Lopez |
a09598 |
RootlessPolyText8,
|
|
Carlos Lopez |
a09598 |
RootlessPolyText16,
|
|
Carlos Lopez |
a09598 |
RootlessImageText8,
|
|
Carlos Lopez |
a09598 |
RootlessImageText16,
|
|
Carlos Lopez |
a09598 |
RootlessImageGlyphBlt,
|
|
Carlos Lopez |
a09598 |
RootlessPolyGlyphBlt,
|
|
Carlos Lopez |
a09598 |
RootlessPushPixels
|
|
Carlos Lopez |
a09598 |
#ifdef NEED_LINEHELPER
|
|
Carlos Lopez |
a09598 |
, NULL
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
};
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Bool
|
|
Carlos Lopez |
a09598 |
RootlessCreateGC(GCPtr pGC)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
RootlessGCRec *gcrec;
|
|
Carlos Lopez |
a09598 |
RootlessScreenRec *s;
|
|
Carlos Lopez |
a09598 |
Bool result;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
SCREEN_UNWRAP(pGC->pScreen, CreateGC);
|
|
Carlos Lopez |
a09598 |
s = (RootlessScreenRec *) pGC->pScreen->
|
|
Carlos Lopez |
a09598 |
devPrivates[rootlessScreenPrivateIndex].ptr;
|
|
Carlos Lopez |
a09598 |
result = s->CreateGC(pGC);
|
|
Carlos Lopez |
a09598 |
gcrec = (RootlessGCRec *) pGC->devPrivates[rootlessGCPrivateIndex].ptr;
|
|
Carlos Lopez |
a09598 |
gcrec->originalOps = NULL; // don't wrap ops yet
|
|
Carlos Lopez |
a09598 |
gcrec->originalFuncs = pGC->funcs;
|
|
Carlos Lopez |
a09598 |
pGC->funcs = &rootlessGCFuncs;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
SCREEN_WRAP(pGC->pScreen, CreateGC);
|
|
Carlos Lopez |
a09598 |
return result;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// GC func wrapping
|
|
Carlos Lopez |
a09598 |
// ValidateGC wraps gcOps iff dest is viewable. All others just unwrap&call.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// GCFUN_UNRAP assumes funcs have been wrapped and
|
|
Carlos Lopez |
a09598 |
// does not assume ops have been wrapped
|
|
Carlos Lopez |
a09598 |
#define GCFUNC_UNWRAP(pGC) \
|
|
Carlos Lopez |
a09598 |
RootlessGCRec *gcrec = (RootlessGCRec *) \
|
|
Carlos Lopez |
a09598 |
(pGC)->devPrivates[rootlessGCPrivateIndex].ptr; \
|
|
Carlos Lopez |
a09598 |
(pGC)->funcs = gcrec->originalFuncs; \
|
|
Carlos Lopez |
a09598 |
if (gcrec->originalOps) { \
|
|
Carlos Lopez |
a09598 |
(pGC)->ops = gcrec->originalOps; \
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define GCFUNC_WRAP(pGC) \
|
|
Carlos Lopez |
a09598 |
gcrec->originalFuncs = (pGC)->funcs; \
|
|
Carlos Lopez |
a09598 |
(pGC)->funcs = &rootlessGCFuncs; \
|
|
Carlos Lopez |
a09598 |
if (gcrec->originalOps) { \
|
|
Carlos Lopez |
a09598 |
gcrec->originalOps = (pGC)->ops; \
|
|
Carlos Lopez |
a09598 |
(pGC)->ops = &rootlessGCOps; \
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Turn drawing on the root into a no-op */
|
|
Carlos Lopez |
a09598 |
#define GC_IS_ROOT(pDst) ((pDst)->type == DRAWABLE_WINDOW \
|
|
Carlos Lopez |
a09598 |
&& IsRoot ((WindowPtr) (pDst)) \
|
|
Carlos Lopez |
a09598 |
&& WINREC ((WindowPtr) (pDst)) == NULL)
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define GC_SKIP_ROOT(pDst) \
|
|
Carlos Lopez |
a09598 |
do { \
|
|
Carlos Lopez |
a09598 |
if (GC_IS_ROOT (pDst)) \
|
|
Carlos Lopez |
a09598 |
return; \
|
|
Carlos Lopez |
a09598 |
} while (0)
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Our main problem when drawing is that we have to make sure that
|
|
Carlos Lopez |
a09598 |
the alpha channel of the windows we're drawing in is always opaque.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
fb makes this harder than it would otherwise be by noticing that a
|
|
Carlos Lopez |
a09598 |
planemask of 0x00ffffff includes all bits when depth=24, and so
|
|
Carlos Lopez |
a09598 |
"optimizes" the pm to 0xffffffff. We work around that by temporarily
|
|
Carlos Lopez |
a09598 |
setting depth=bpp while changing the GC.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Anyway, so the normal situation (in 32 bit mode) is that the
|
|
Carlos Lopez |
a09598 |
planemask is 0x00ffffff and thus fb leaves the alpha channel alone
|
|
Carlos Lopez |
a09598 |
(and it's opaque initially, so things work out).
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
But there's a problem with drawing with a planemask that doesn't
|
|
Carlos Lopez |
a09598 |
have all bits set - it normally causes fb to fall off its fastest
|
|
Carlos Lopez |
a09598 |
paths when blitting and filling.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
So my solution to that is to try to recognize when we can relax the
|
|
Carlos Lopez |
a09598 |
planemask back to ~0, and do that for the duration of the drawing
|
|
Carlos Lopez |
a09598 |
operation, setting the alpha channel in fg/bg pixels to opaque at
|
|
Carlos Lopez |
a09598 |
the same time. We can do this when drawing op is GXcopy. We can also
|
|
Carlos Lopez |
a09598 |
do it when copying from another window (since its alpha channel must
|
|
Carlos Lopez |
a09598 |
also be opaque).
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Note that even when we can't set planemask to all ones, fbBlt may
|
|
Carlos Lopez |
a09598 |
still choose altivec'd code if it's GXcopy and a forwards copy. This
|
|
Carlos Lopez |
a09598 |
is mainly intended for copying from pixmaps to windows. The copy
|
|
Carlos Lopez |
a09598 |
operation used sets alpha to opaque.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
The three macros below are used to implement this, drawing ops look
|
|
Carlos Lopez |
a09598 |
something like this:
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
OP {
|
|
Carlos Lopez |
a09598 |
GC_SAVE (gc);
|
|
Carlos Lopez |
a09598 |
GCFUNC_UNWRAP (gc);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
...
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (can_accel_xxx (..) && otherwise-suitable)
|
|
Carlos Lopez |
a09598 |
GC_UNSET_PM (gc, dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
gc->funcs->OP (gc, ...);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_RESTORE (gc, dst);
|
|
Carlos Lopez |
a09598 |
GCFUNC_WRAP (gc);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define GC_SAVE(pGC) \
|
|
Carlos Lopez |
a09598 |
unsigned long _save_fg = (pGC)->fgPixel; \
|
|
Carlos Lopez |
a09598 |
unsigned long _save_bg = (pGC)->bgPixel; \
|
|
Carlos Lopez |
a09598 |
unsigned long _save_pm = (pGC)->planemask; \
|
|
Carlos Lopez |
a09598 |
Bool _changed = FALSE
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define GC_RESTORE(pGC, pDraw) \
|
|
Carlos Lopez |
a09598 |
do { \
|
|
Carlos Lopez |
a09598 |
if (_changed) { \
|
|
Carlos Lopez |
a09598 |
unsigned int depth = (pDraw)->depth; \
|
|
Carlos Lopez |
a09598 |
(pGC)->fgPixel = _save_fg; \
|
|
Carlos Lopez |
a09598 |
(pGC)->bgPixel = _save_bg; \
|
|
Carlos Lopez |
a09598 |
(pGC)->planemask = _save_pm; \
|
|
Carlos Lopez |
a09598 |
(pDraw)->depth = (pDraw)->bitsPerPixel; \
|
|
Carlos Lopez |
a09598 |
validate_gc (pGC, GCForeground | GCBackground \
|
|
Carlos Lopez |
a09598 |
| GCPlaneMask, pDraw); \
|
|
Carlos Lopez |
a09598 |
(pDraw)->depth = depth; \
|
|
Carlos Lopez |
a09598 |
} \
|
|
Carlos Lopez |
a09598 |
} while (0)
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define GC_UNSET_PM(pGC, pDraw) \
|
|
Carlos Lopez |
a09598 |
do { \
|
|
Carlos Lopez |
a09598 |
unsigned int mask = RootlessAlphaMask ((pDraw)->bitsPerPixel); \
|
|
Carlos Lopez |
a09598 |
if (((pGC)->planemask & mask) != mask) { \
|
|
Carlos Lopez |
a09598 |
unsigned int depth = (pDraw)->depth; \
|
|
Carlos Lopez |
a09598 |
(pGC)->fgPixel |= mask; \
|
|
Carlos Lopez |
a09598 |
(pGC)->bgPixel |= mask; \
|
|
Carlos Lopez |
a09598 |
(pGC)->planemask |= mask; \
|
|
Carlos Lopez |
a09598 |
(pDraw)->depth = (pDraw)->bitsPerPixel; \
|
|
Carlos Lopez |
a09598 |
validate_gc (pGC, GCForeground \
|
|
Carlos Lopez |
a09598 |
| GCBackground | GCPlaneMask, pDraw); \
|
|
Carlos Lopez |
a09598 |
(pDraw)->depth = depth; \
|
|
Carlos Lopez |
a09598 |
_changed = TRUE; \
|
|
Carlos Lopez |
a09598 |
} \
|
|
Carlos Lopez |
a09598 |
} while (0)
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
RootlessGCRec *gcrec = (RootlessGCRec *)
|
|
Carlos Lopez |
a09598 |
(pGC)->devPrivates[rootlessGCPrivateIndex].ptr;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pGC->funcs->ValidateGC(pGC, changes, pDrawable);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (((WindowPtr) pDrawable)->viewable)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
gcrec->originalOps = pGC->ops;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static RootlessWindowRec *
|
|
Carlos Lopez |
a09598 |
can_accel_blit (DrawablePtr pDraw, GCPtr pGC)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
WindowPtr pTop;
|
|
Carlos Lopez |
a09598 |
RootlessWindowRec *winRec;
|
|
Carlos Lopez |
a09598 |
unsigned int pm;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (pGC->alu != GXcopy)
|
|
Carlos Lopez |
a09598 |
return NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (pDraw->type != DRAWABLE_WINDOW)
|
|
Carlos Lopez |
a09598 |
return NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pm = ~RootlessAlphaMask (pDraw->bitsPerPixel);
|
|
Carlos Lopez |
a09598 |
if ((pGC->planemask & pm) != pm)
|
|
Carlos Lopez |
a09598 |
return NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pTop = TopLevelParent ((WindowPtr) pDraw);
|
|
Carlos Lopez |
a09598 |
if (pTop == NULL)
|
|
Carlos Lopez |
a09598 |
return NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
winRec = WINREC(pTop);
|
|
Carlos Lopez |
a09598 |
if (winRec == NULL)
|
|
Carlos Lopez |
a09598 |
return NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return winRec;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static inline RootlessWindowRec *
|
|
Carlos Lopez |
a09598 |
can_accel_fill (DrawablePtr pDraw, GCPtr pGC)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (pGC->fillStyle != FillSolid)
|
|
Carlos Lopez |
a09598 |
return NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return can_accel_blit (pDraw, pGC);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static unsigned int
|
|
Carlos Lopez |
a09598 |
box_bytes (DrawablePtr pDraw, BoxRec *box)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
unsigned int pixels;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pixels = (box->x2 - box->x1) * (box->y2 - box->y1);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return pixels * (pDraw->bitsPerPixel >> 3);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
RootlessValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GCFUNC_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
gcrec->originalOps = NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (pDrawable->type == DRAWABLE_WINDOW)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
/* Prevent fb relaxing planemask by telling it we use all
|
|
Carlos Lopez |
a09598 |
bits temporarily. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
unsigned int depth = pDrawable->depth;
|
|
Carlos Lopez |
a09598 |
pDrawable->depth = pDrawable->bitsPerPixel;
|
|
Carlos Lopez |
a09598 |
pGC->planemask &= ~RootlessAlphaMask (pDrawable->bitsPerPixel);
|
|
Carlos Lopez |
a09598 |
validate_gc (pGC, changes | GCPlaneMask, pDrawable);
|
|
Carlos Lopez |
a09598 |
pDrawable->depth = depth;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
pGC->funcs->ValidateGC(pGC, changes, pDrawable);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCFUNC_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessChangeGC(GCPtr pGC, unsigned long mask)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GCFUNC_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
pGC->funcs->ChangeGC(pGC, mask);
|
|
Carlos Lopez |
a09598 |
GCFUNC_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GCFUNC_UNWRAP(pGCDst);
|
|
Carlos Lopez |
a09598 |
pGCDst->funcs->CopyGC(pGCSrc, mask, pGCDst);
|
|
Carlos Lopez |
a09598 |
GCFUNC_WRAP(pGCDst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessDestroyGC(GCPtr pGC)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GCFUNC_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
pGC->funcs->DestroyGC(pGC);
|
|
Carlos Lopez |
a09598 |
GCFUNC_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GCFUNC_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
|
|
Carlos Lopez |
a09598 |
GCFUNC_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessDestroyClip(GCPtr pGC)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GCFUNC_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
pGC->funcs->DestroyClip(pGC);
|
|
Carlos Lopez |
a09598 |
GCFUNC_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GCFUNC_UNWRAP(pgcDst);
|
|
Carlos Lopez |
a09598 |
pgcDst->funcs->CopyClip(pgcDst, pgcSrc);
|
|
Carlos Lopez |
a09598 |
GCFUNC_WRAP(pgcDst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// GC ops
|
|
Carlos Lopez |
a09598 |
// We can't use shadowfb because shadowfb assumes one pixmap
|
|
Carlos Lopez |
a09598 |
// and our root window is a special case.
|
|
Carlos Lopez |
a09598 |
// So much of this code is copied from shadowfb.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// assumes both funcs and ops are wrapped
|
|
Carlos Lopez |
a09598 |
#define GCOP_UNWRAP(pGC) \
|
|
Carlos Lopez |
a09598 |
RootlessGCRec *gcrec = (RootlessGCRec *) \
|
|
Carlos Lopez |
a09598 |
(pGC)->devPrivates[rootlessGCPrivateIndex].ptr; \
|
|
Carlos Lopez |
a09598 |
GCFuncs *saveFuncs = pGC->funcs; \
|
|
Carlos Lopez |
a09598 |
(pGC)->funcs = gcrec->originalFuncs; \
|
|
Carlos Lopez |
a09598 |
(pGC)->ops = gcrec->originalOps;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define GCOP_WRAP(pGC) \
|
|
Carlos Lopez |
a09598 |
gcrec->originalOps = (pGC)->ops; \
|
|
Carlos Lopez |
a09598 |
(pGC)->funcs = saveFuncs; \
|
|
Carlos Lopez |
a09598 |
(pGC)->ops = &rootlessGCOps;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
|
|
Carlos Lopez |
a09598 |
DDXPointPtr pptInit, int *pwidthInit, int sorted)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SAVE (pGC);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("fill spans start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (nInit <= 0) {
|
|
Carlos Lopez |
a09598 |
pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
DDXPointPtr ppt = pptInit;
|
|
Carlos Lopez |
a09598 |
int *pwidth = pwidthInit;
|
|
Carlos Lopez |
a09598 |
int i = nInit;
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = ppt->x;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + *pwidth;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 = ppt->y;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(--i) {
|
|
Carlos Lopez |
a09598 |
ppt++;
|
|
Carlos Lopez |
a09598 |
pwidthInit++;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > ppt->x)
|
|
Carlos Lopez |
a09598 |
box.x1 = ppt->x;
|
|
Carlos Lopez |
a09598 |
if(box.x2 < (ppt->x + *pwidth))
|
|
Carlos Lopez |
a09598 |
box.x2 = ppt->x + *pwidth;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > ppt->y)
|
|
Carlos Lopez |
a09598 |
box.y1 = ppt->y;
|
|
Carlos Lopez |
a09598 |
else if(box.y2 < ppt->y)
|
|
Carlos Lopez |
a09598 |
box.y2 = ppt->y;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.y2++;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (can_accel_fill (dst, pGC)
|
|
Carlos Lopez |
a09598 |
&& box_bytes (dst, &box) >= xp_fill_bytes_threshold)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_UNSET_PM (pGC, dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_RESTORE (pGC, dst);
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("fill spans end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
RootlessSetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc,
|
|
Carlos Lopez |
a09598 |
DDXPointPtr pptInit, int *pwidthInit,
|
|
Carlos Lopez |
a09598 |
int nspans, int sorted)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("set spans start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (nspans <= 0) {
|
|
Carlos Lopez |
a09598 |
pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit,
|
|
Carlos Lopez |
a09598 |
nspans, sorted);
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
DDXPointPtr ppt = pptInit;
|
|
Carlos Lopez |
a09598 |
int *pwidth = pwidthInit;
|
|
Carlos Lopez |
a09598 |
int i = nspans;
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = ppt->x;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + *pwidth;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 = ppt->y;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(--i) {
|
|
Carlos Lopez |
a09598 |
ppt++;
|
|
Carlos Lopez |
a09598 |
pwidth++;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > ppt->x)
|
|
Carlos Lopez |
a09598 |
box.x1 = ppt->x;
|
|
Carlos Lopez |
a09598 |
if(box.x2 < (ppt->x + *pwidth))
|
|
Carlos Lopez |
a09598 |
box.x2 = ppt->x + *pwidth;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > ppt->y)
|
|
Carlos Lopez |
a09598 |
box.y1 = ppt->y;
|
|
Carlos Lopez |
a09598 |
else if(box.y2 < ppt->y)
|
|
Carlos Lopez |
a09598 |
box.y2 = ppt->y;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.y2++;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit,
|
|
Carlos Lopez |
a09598 |
nspans, sorted);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("set spans end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
RootlessPutImage(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int depth, int x, int y, int w, int h,
|
|
Carlos Lopez |
a09598 |
int leftPad, int format, char *pBits)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("put image start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->PutImage(dst, pGC, depth, x,y,w,h, leftPad, format, pBits);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = x + dst->x;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + w;
|
|
Carlos Lopez |
a09598 |
box.y1 = y + dst->y;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + h;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("put image end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is *dest* rect */
|
|
Carlos Lopez |
a09598 |
static RegionPtr
|
|
Carlos Lopez |
a09598 |
RootlessCopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int srcx, int srcy, int w, int h,
|
|
Carlos Lopez |
a09598 |
int dstx, int dsty)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
RegionPtr result;
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
GC_SAVE (pGC);
|
|
Carlos Lopez |
a09598 |
Bool src_drawing = FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (GC_IS_ROOT (dst) || GC_IS_ROOT (pSrc))
|
|
Carlos Lopez |
a09598 |
return NULL; /* nothing exposed */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("copy area start (src 0x%x, dst 0x%x)\n", pSrc, dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr)pSrc))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
unsigned int bytes;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* If both source and dest are windows, and we're doing
|
|
Carlos Lopez |
a09598 |
a simple copy operation, we can remove the alpha-protecting
|
|
Carlos Lopez |
a09598 |
planemask (since source has opaque alpha as well) */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
bytes = w * h * (pSrc->depth >> 3);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (bytes >= xp_copy_bytes_threshold && can_accel_blit (pSrc, pGC))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_UNSET_PM (pGC, dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) pSrc);
|
|
Carlos Lopez |
a09598 |
src_drawing = TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
result = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = dstx + dst->x;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + w;
|
|
Carlos Lopez |
a09598 |
box.y1 = dsty + dst->y;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + h;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
if (src_drawing)
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) pSrc);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_RESTORE (pGC, dst);
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("copy area end\n");
|
|
Carlos Lopez |
a09598 |
return result;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is *dest* rect */
|
|
Carlos Lopez |
a09598 |
static RegionPtr RootlessCopyPlane(DrawablePtr pSrc, DrawablePtr dst,
|
|
Carlos Lopez |
a09598 |
GCPtr pGC, int srcx, int srcy,
|
|
Carlos Lopez |
a09598 |
int w, int h, int dstx, int dsty,
|
|
Carlos Lopez |
a09598 |
unsigned long plane)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
RegionPtr result;
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
Bool src_drawing = FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (GC_IS_ROOT (dst) || GC_IS_ROOT (pSrc))
|
|
Carlos Lopez |
a09598 |
return NULL; /* nothing exposed */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("copy plane start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr)pSrc)) {
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) pSrc);
|
|
Carlos Lopez |
a09598 |
src_drawing = TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
result = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h,
|
|
Carlos Lopez |
a09598 |
dstx, dsty, plane);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = dstx + dst->x;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + w;
|
|
Carlos Lopez |
a09598 |
box.y1 = dsty + dst->y;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + h;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
if (src_drawing)
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) pSrc);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("copy plane end\n");
|
|
Carlos Lopez |
a09598 |
return result;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Options for size of changed area:
|
|
Carlos Lopez |
a09598 |
// 0 = box per point
|
|
Carlos Lopez |
a09598 |
// 1 = big box around all points
|
|
Carlos Lopez |
a09598 |
// 2 = accumulate point in 20 pixel radius
|
|
Carlos Lopez |
a09598 |
#define ROOTLESS_CHANGED_AREA 1
|
|
Carlos Lopez |
a09598 |
#define abs(a) ((a) > 0 ? (a) : -(a))
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is box around all points */
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyPoint(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int mode, int npt, DDXPointPtr pptInit)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("polypoint start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (npt > 0) {
|
|
Carlos Lopez |
a09598 |
#if ROOTLESS_CHANGED_AREA==0
|
|
Carlos Lopez |
a09598 |
// box per point
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while (npt) {
|
|
Carlos Lopez |
a09598 |
box.x1 = pptInit->x;
|
|
Carlos Lopez |
a09598 |
box.y1 = pptInit->y;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + 1;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + 1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
npt--;
|
|
Carlos Lopez |
a09598 |
pptInit++;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#elif ROOTLESS_CHANGED_AREA==1
|
|
Carlos Lopez |
a09598 |
// one big box
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 = pptInit->x;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 = pptInit->y;
|
|
Carlos Lopez |
a09598 |
while(--npt) {
|
|
Carlos Lopez |
a09598 |
pptInit++;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > pptInit->x)
|
|
Carlos Lopez |
a09598 |
box.x1 = pptInit->x;
|
|
Carlos Lopez |
a09598 |
else if(box.x2 < pptInit->x)
|
|
Carlos Lopez |
a09598 |
box.x2 = pptInit->x;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > pptInit->y)
|
|
Carlos Lopez |
a09598 |
box.y1 = pptInit->y;
|
|
Carlos Lopez |
a09598 |
else if(box.y2 < pptInit->y)
|
|
Carlos Lopez |
a09598 |
box.y2 = pptInit->y;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2++;
|
|
Carlos Lopez |
a09598 |
box.y2++;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#elif ROOTLESS_CHANGED_AREA==2
|
|
Carlos Lopez |
a09598 |
// clever(?) method: accumulate point in 20-pixel radius
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
int firstx, firsty;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 = firstx = pptInit->x;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 = firsty = pptInit->y;
|
|
Carlos Lopez |
a09598 |
while(--npt) {
|
|
Carlos Lopez |
a09598 |
pptInit++;
|
|
Carlos Lopez |
a09598 |
if (abs(pptInit->x - firstx) > 20 ||
|
|
Carlos Lopez |
a09598 |
abs(pptInit->y - firsty) > 20) {
|
|
Carlos Lopez |
a09598 |
box.x2++;
|
|
Carlos Lopez |
a09598 |
box.y2++;
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 = firstx = pptInit->x;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 = firsty = pptInit->y;
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
if (box.x1 > pptInit->x) box.x1 = pptInit->x;
|
|
Carlos Lopez |
a09598 |
else if (box.x2 < pptInit->x) box.x2 = pptInit->x;
|
|
Carlos Lopez |
a09598 |
if (box.y1 > pptInit->y) box.y1 = pptInit->y;
|
|
Carlos Lopez |
a09598 |
else if (box.y2 < pptInit->y) box.y2 = pptInit->y;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
box.x2++;
|
|
Carlos Lopez |
a09598 |
box.y2++;
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
#endif /* ROOTLESS_CHANGED_AREA */
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("polypoint end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#undef ROOTLESS_CHANGED_AREA
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is box around each line */
|
|
Carlos Lopez |
a09598 |
static void RootlessPolylines(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int mode, int npt, DDXPointPtr pptInit)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("poly lines start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->Polylines(dst, pGC, mode, npt, pptInit);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (npt > 0) {
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
int extra = pGC->lineWidth >> 1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 = pptInit->x;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 = pptInit->y;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(npt > 1) {
|
|
Carlos Lopez |
a09598 |
if(pGC->joinStyle == JoinMiter)
|
|
Carlos Lopez |
a09598 |
extra = 6 * pGC->lineWidth;
|
|
Carlos Lopez |
a09598 |
else if(pGC->capStyle == CapProjecting)
|
|
Carlos Lopez |
a09598 |
extra = pGC->lineWidth;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(mode == CoordModePrevious) {
|
|
Carlos Lopez |
a09598 |
int x = box.x1;
|
|
Carlos Lopez |
a09598 |
int y = box.y1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(--npt) {
|
|
Carlos Lopez |
a09598 |
pptInit++;
|
|
Carlos Lopez |
a09598 |
x += pptInit->x;
|
|
Carlos Lopez |
a09598 |
y += pptInit->y;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > x)
|
|
Carlos Lopez |
a09598 |
box.x1 = x;
|
|
Carlos Lopez |
a09598 |
else if(box.x2 < x)
|
|
Carlos Lopez |
a09598 |
box.x2 = x;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > y)
|
|
Carlos Lopez |
a09598 |
box.y1 = y;
|
|
Carlos Lopez |
a09598 |
else if(box.y2 < y)
|
|
Carlos Lopez |
a09598 |
box.y2 = y;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
while(--npt) {
|
|
Carlos Lopez |
a09598 |
pptInit++;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > pptInit->x)
|
|
Carlos Lopez |
a09598 |
box.x1 = pptInit->x;
|
|
Carlos Lopez |
a09598 |
else if(box.x2 < pptInit->x)
|
|
Carlos Lopez |
a09598 |
box.x2 = pptInit->x;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > pptInit->y)
|
|
Carlos Lopez |
a09598 |
box.y1 = pptInit->y;
|
|
Carlos Lopez |
a09598 |
else if(box.y2 < pptInit->y)
|
|
Carlos Lopez |
a09598 |
box.y2 = pptInit->y;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2++;
|
|
Carlos Lopez |
a09598 |
box.y2++;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(extra) {
|
|
Carlos Lopez |
a09598 |
box.x1 -= extra;
|
|
Carlos Lopez |
a09598 |
box.x2 += extra;
|
|
Carlos Lopez |
a09598 |
box.y1 -= extra;
|
|
Carlos Lopez |
a09598 |
box.y2 += extra;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("poly lines end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is box around each line segment */
|
|
Carlos Lopez |
a09598 |
static void RootlessPolySegment(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int nseg, xSegment *pSeg)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("poly segment start (win 0x%x)\n", dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->PolySegment(dst, pGC, nseg, pSeg);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (nseg > 0) {
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
int extra = pGC->lineWidth;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(pGC->capStyle != CapProjecting)
|
|
Carlos Lopez |
a09598 |
extra >>= 1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(pSeg->x2 > pSeg->x1) {
|
|
Carlos Lopez |
a09598 |
box.x1 = pSeg->x1;
|
|
Carlos Lopez |
a09598 |
box.x2 = pSeg->x2;
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
box.x2 = pSeg->x1;
|
|
Carlos Lopez |
a09598 |
box.x1 = pSeg->x2;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(pSeg->y2 > pSeg->y1) {
|
|
Carlos Lopez |
a09598 |
box.y1 = pSeg->y1;
|
|
Carlos Lopez |
a09598 |
box.y2 = pSeg->y2;
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
box.y2 = pSeg->y1;
|
|
Carlos Lopez |
a09598 |
box.y1 = pSeg->y2;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(--nseg) {
|
|
Carlos Lopez |
a09598 |
pSeg++;
|
|
Carlos Lopez |
a09598 |
if(pSeg->x2 > pSeg->x1) {
|
|
Carlos Lopez |
a09598 |
if(pSeg->x1 < box.x1) box.x1 = pSeg->x1;
|
|
Carlos Lopez |
a09598 |
if(pSeg->x2 > box.x2) box.x2 = pSeg->x2;
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
if(pSeg->x2 < box.x1) box.x1 = pSeg->x2;
|
|
Carlos Lopez |
a09598 |
if(pSeg->x1 > box.x2) box.x2 = pSeg->x1;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
if(pSeg->y2 > pSeg->y1) {
|
|
Carlos Lopez |
a09598 |
if(pSeg->y1 < box.y1) box.y1 = pSeg->y1;
|
|
Carlos Lopez |
a09598 |
if(pSeg->y2 > box.y2) box.y2 = pSeg->y2;
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
if(pSeg->y2 < box.y1) box.y1 = pSeg->y2;
|
|
Carlos Lopez |
a09598 |
if(pSeg->y1 > box.y2) box.y2 = pSeg->y1;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2++;
|
|
Carlos Lopez |
a09598 |
box.y2++;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(extra) {
|
|
Carlos Lopez |
a09598 |
box.x1 -= extra;
|
|
Carlos Lopez |
a09598 |
box.x2 += extra;
|
|
Carlos Lopez |
a09598 |
box.y1 -= extra;
|
|
Carlos Lopez |
a09598 |
box.y2 += extra;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("poly segment end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is box around each line (not entire rects) */
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyRectangle(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int nRects, xRectangle *pRects)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("poly rectangle start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->PolyRectangle(dst, pGC, nRects, pRects);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (nRects > 0) {
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
int offset1, offset2, offset3;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
offset2 = pGC->lineWidth;
|
|
Carlos Lopez |
a09598 |
if(!offset2) offset2 = 1;
|
|
Carlos Lopez |
a09598 |
offset1 = offset2 >> 1;
|
|
Carlos Lopez |
a09598 |
offset3 = offset2 - offset1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(nRects--) {
|
|
Carlos Lopez |
a09598 |
box.x1 = pRects->x - offset1;
|
|
Carlos Lopez |
a09598 |
box.y1 = pRects->y - offset1;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + pRects->width + offset2;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + offset2;
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = pRects->x - offset1;
|
|
Carlos Lopez |
a09598 |
box.y1 = pRects->y + offset3;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + offset2;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + pRects->height - offset2;
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = pRects->x + pRects->width - offset1;
|
|
Carlos Lopez |
a09598 |
box.y1 = pRects->y + offset3;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + offset2;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + pRects->height - offset2;
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = pRects->x - offset1;
|
|
Carlos Lopez |
a09598 |
box.y1 = pRects->y + pRects->height - offset1;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + pRects->width + offset2;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + offset2;
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pRects++;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("poly rectangle end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is box around each arc (assumes all arcs are 360 degrees) */
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("poly arc start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->PolyArc(dst, pGC, narcs, parcs);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (narcs > 0) {
|
|
Carlos Lopez |
a09598 |
int extra = pGC->lineWidth >> 1;
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = parcs->x;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + parcs->width;
|
|
Carlos Lopez |
a09598 |
box.y1 = parcs->y;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + parcs->height;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* should I break these up instead ? */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(--narcs) {
|
|
Carlos Lopez |
a09598 |
parcs++;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > parcs->x)
|
|
Carlos Lopez |
a09598 |
box.x1 = parcs->x;
|
|
Carlos Lopez |
a09598 |
if(box.x2 < (parcs->x + parcs->width))
|
|
Carlos Lopez |
a09598 |
box.x2 = parcs->x + parcs->width;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > parcs->y)
|
|
Carlos Lopez |
a09598 |
box.y1 = parcs->y;
|
|
Carlos Lopez |
a09598 |
if(box.y2 < (parcs->y + parcs->height))
|
|
Carlos Lopez |
a09598 |
box.y2 = parcs->y + parcs->height;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(extra) {
|
|
Carlos Lopez |
a09598 |
box.x1 -= extra;
|
|
Carlos Lopez |
a09598 |
box.x2 += extra;
|
|
Carlos Lopez |
a09598 |
box.y1 -= extra;
|
|
Carlos Lopez |
a09598 |
box.y2 += extra;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2++;
|
|
Carlos Lopez |
a09598 |
box.y2++;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("poly arc end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is box around each poly */
|
|
Carlos Lopez |
a09598 |
static void RootlessFillPolygon(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int shape, int mode, int count,
|
|
Carlos Lopez |
a09598 |
DDXPointPtr pptInit)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SAVE (pGC);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("fill poly start (win 0x%x, fillStyle 0x%x)\n", dst,
|
|
Carlos Lopez |
a09598 |
pGC->fillStyle);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (count <= 2) {
|
|
Carlos Lopez |
a09598 |
pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
DDXPointPtr ppt = pptInit;
|
|
Carlos Lopez |
a09598 |
int i = count;
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 = ppt->x;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 = ppt->y;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(mode != CoordModeOrigin) {
|
|
Carlos Lopez |
a09598 |
int x = box.x1;
|
|
Carlos Lopez |
a09598 |
int y = box.y1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(--i) {
|
|
Carlos Lopez |
a09598 |
ppt++;
|
|
Carlos Lopez |
a09598 |
x += ppt->x;
|
|
Carlos Lopez |
a09598 |
y += ppt->y;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > x)
|
|
Carlos Lopez |
a09598 |
box.x1 = x;
|
|
Carlos Lopez |
a09598 |
else if(box.x2 < x)
|
|
Carlos Lopez |
a09598 |
box.x2 = x;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > y)
|
|
Carlos Lopez |
a09598 |
box.y1 = y;
|
|
Carlos Lopez |
a09598 |
else if(box.y2 < y)
|
|
Carlos Lopez |
a09598 |
box.y2 = y;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
while(--i) {
|
|
Carlos Lopez |
a09598 |
ppt++;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > ppt->x)
|
|
Carlos Lopez |
a09598 |
box.x1 = ppt->x;
|
|
Carlos Lopez |
a09598 |
else if(box.x2 < ppt->x)
|
|
Carlos Lopez |
a09598 |
box.x2 = ppt->x;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > ppt->y)
|
|
Carlos Lopez |
a09598 |
box.y1 = ppt->y;
|
|
Carlos Lopez |
a09598 |
else if(box.y2 < ppt->y)
|
|
Carlos Lopez |
a09598 |
box.y2 = ppt->y;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2++;
|
|
Carlos Lopez |
a09598 |
box.y2++;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (can_accel_fill (dst, pGC)
|
|
Carlos Lopez |
a09598 |
&& box_bytes (dst, &box) >= xp_fill_bytes_threshold)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_UNSET_PM (pGC, dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_RESTORE (pGC, dst);
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("fill poly end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is the rects */
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyFillRect(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int nRectsInit, xRectangle *pRectsInit)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SAVE (pGC);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("fill rect start (win 0x%x, fillStyle 0x%x)\n", dst,
|
|
Carlos Lopez |
a09598 |
pGC->fillStyle);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (nRectsInit <= 0) {
|
|
Carlos Lopez |
a09598 |
pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
xRectangle *pRects = pRectsInit;
|
|
Carlos Lopez |
a09598 |
int nRects = nRectsInit;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = pRects->x;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + pRects->width;
|
|
Carlos Lopez |
a09598 |
box.y1 = pRects->y;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + pRects->height;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(--nRects) {
|
|
Carlos Lopez |
a09598 |
pRects++;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > pRects->x)
|
|
Carlos Lopez |
a09598 |
box.x1 = pRects->x;
|
|
Carlos Lopez |
a09598 |
if(box.x2 < (pRects->x + pRects->width))
|
|
Carlos Lopez |
a09598 |
box.x2 = pRects->x + pRects->width;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > pRects->y)
|
|
Carlos Lopez |
a09598 |
box.y1 = pRects->y;
|
|
Carlos Lopez |
a09598 |
if(box.y2 < (pRects->y + pRects->height))
|
|
Carlos Lopez |
a09598 |
box.y2 = pRects->y + pRects->height;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* cfb messes with the pRectsInit so we have to do our
|
|
Carlos Lopez |
a09598 |
calculations first */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (can_accel_fill (dst, pGC)
|
|
Carlos Lopez |
a09598 |
&& box_bytes (dst, &box) >= xp_fill_bytes_threshold)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_UNSET_PM (pGC, dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pGC->ops->PolyFillRect (dst, pGC, nRectsInit, pRectsInit);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_RESTORE (pGC, dst);
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("fill rect end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is box around each arc (assuming arcs are all 360 degrees) */
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyFillArc(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int narcs, xArc *parcs)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SAVE (pGC);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("fill arc start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (narcs > 0) {
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
int i;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = parcs->x;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + parcs->width;
|
|
Carlos Lopez |
a09598 |
box.y1 = parcs->y;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + parcs->height;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* should I break these up instead ? */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
for (i = 0; i < narcs; i++)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if(box.x1 > parcs[i].x)
|
|
Carlos Lopez |
a09598 |
box.x1 = parcs[i].x;
|
|
Carlos Lopez |
a09598 |
if(box.x2 < (parcs[i].x + parcs[i].width))
|
|
Carlos Lopez |
a09598 |
box.x2 = parcs[i].x + parcs[i].width;
|
|
Carlos Lopez |
a09598 |
if(box.y1 > parcs[i].y)
|
|
Carlos Lopez |
a09598 |
box.y1 = parcs[i].y;
|
|
Carlos Lopez |
a09598 |
if(box.y2 < (parcs[i].y + parcs[i].height))
|
|
Carlos Lopez |
a09598 |
box.y2 = parcs[i].y + parcs[i].height;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (can_accel_fill (dst, pGC)
|
|
Carlos Lopez |
a09598 |
&& box_bytes (dst, &box) >= xp_fill_bytes_threshold)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_UNSET_PM (pGC, dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pGC->ops->PolyFillArc(dst, pGC, narcs, parcs);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
pGC->ops->PolyFillArc(dst, pGC, narcs, parcs);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_RESTORE (pGC, dst);
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("fill arc end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessImageText8(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int x, int y, int count, char *chars)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SAVE (pGC);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("imagetext8 start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (count > 0) {
|
|
Carlos Lopez |
a09598 |
int top, bot, Min, Max;
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
|
|
Carlos Lopez |
a09598 |
bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
|
|
Carlos Lopez |
a09598 |
if(Min > 0) Min = 0;
|
|
Carlos Lopez |
a09598 |
Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
|
|
Carlos Lopez |
a09598 |
if(Max < 0) Max = 0;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* ugh */
|
|
Carlos Lopez |
a09598 |
box.x1 = dst->x + x + Min +
|
|
Carlos Lopez |
a09598 |
FONTMINBOUNDS(pGC->font, leftSideBearing);
|
|
Carlos Lopez |
a09598 |
box.x2 = dst->x + x + Max +
|
|
Carlos Lopez |
a09598 |
FONTMAXBOUNDS(pGC->font, rightSideBearing);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.y1 = dst->y + y - top;
|
|
Carlos Lopez |
a09598 |
box.y2 = dst->y + y + bot;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (can_accel_fill (dst, pGC)
|
|
Carlos Lopez |
a09598 |
&& box_bytes (dst, &box) >= xp_fill_bytes_threshold)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_UNSET_PM (pGC, dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_RESTORE (pGC, dst);
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("imagetext8 end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static int RootlessPolyText8(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int x, int y, int count, char *chars)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int width; // the result, sorta
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (GC_IS_ROOT (dst))
|
|
Carlos Lopez |
a09598 |
return 0; /* FIXME: ok? */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("polytext8 start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
width = pGC->ops->PolyText8(dst, pGC, x, y, count, chars);
|
|
Carlos Lopez |
a09598 |
width -= x;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(width > 0) {
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* ugh */
|
|
Carlos Lopez |
a09598 |
box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
|
|
Carlos Lopez |
a09598 |
box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(count > 1) {
|
|
Carlos Lopez |
a09598 |
if(width > 0) box.x2 += width;
|
|
Carlos Lopez |
a09598 |
else box.x1 += width;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
|
|
Carlos Lopez |
a09598 |
box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("polytext8 end\n");
|
|
Carlos Lopez |
a09598 |
return (width + x);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessImageText16(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int x, int y, int count, unsigned short *chars)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SAVE (pGC);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("imagetext16 start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (count > 0) {
|
|
Carlos Lopez |
a09598 |
int top, bot, Min, Max;
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
|
|
Carlos Lopez |
a09598 |
bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
|
|
Carlos Lopez |
a09598 |
if(Min > 0) Min = 0;
|
|
Carlos Lopez |
a09598 |
Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
|
|
Carlos Lopez |
a09598 |
if(Max < 0) Max = 0;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* ugh */
|
|
Carlos Lopez |
a09598 |
box.x1 = dst->x + x + Min +
|
|
Carlos Lopez |
a09598 |
FONTMINBOUNDS(pGC->font, leftSideBearing);
|
|
Carlos Lopez |
a09598 |
box.x2 = dst->x + x + Max +
|
|
Carlos Lopez |
a09598 |
FONTMAXBOUNDS(pGC->font, rightSideBearing);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.y1 = dst->y + y - top;
|
|
Carlos Lopez |
a09598 |
box.y2 = dst->y + y + bot;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (can_accel_fill (dst, pGC)
|
|
Carlos Lopez |
a09598 |
&& box_bytes (dst, &box) >= xp_fill_bytes_threshold)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_UNSET_PM (pGC, dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_RESTORE (pGC, dst);
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("imagetext16 end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static int RootlessPolyText16(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int x, int y, int count, unsigned short *chars)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int width; // the result, sorta
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (GC_IS_ROOT (dst))
|
|
Carlos Lopez |
a09598 |
return 0; /* FIXME: ok? */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("polytext16 start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
width = pGC->ops->PolyText16(dst, pGC, x, y, count, chars);
|
|
Carlos Lopez |
a09598 |
width -= x;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (width > 0) {
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* ugh */
|
|
Carlos Lopez |
a09598 |
box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
|
|
Carlos Lopez |
a09598 |
box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(count > 1) {
|
|
Carlos Lopez |
a09598 |
if(width > 0) box.x2 += width;
|
|
Carlos Lopez |
a09598 |
else box.x1 += width;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
|
|
Carlos Lopez |
a09598 |
box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("polytext16 end\n");
|
|
Carlos Lopez |
a09598 |
return width + x;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int x, int y, unsigned int nglyph,
|
|
Carlos Lopez |
a09598 |
CharInfoPtr *ppci, pointer unused)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("imageglyph start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyph, ppci, unused);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (nglyph > 0) {
|
|
Carlos Lopez |
a09598 |
int top, bot, width = 0;
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
|
|
Carlos Lopez |
a09598 |
bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = ppci[0]->metrics.leftSideBearing;
|
|
Carlos Lopez |
a09598 |
if(box.x1 > 0) box.x1 = 0;
|
|
Carlos Lopez |
a09598 |
box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing -
|
|
Carlos Lopez |
a09598 |
ppci[nglyph - 1]->metrics.characterWidth;
|
|
Carlos Lopez |
a09598 |
if(box.x2 < 0) box.x2 = 0;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x2 += dst->x + x;
|
|
Carlos Lopez |
a09598 |
box.x1 += dst->x + x;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(nglyph--) {
|
|
Carlos Lopez |
a09598 |
width += (*ppci)->metrics.characterWidth;
|
|
Carlos Lopez |
a09598 |
ppci++;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(width > 0)
|
|
Carlos Lopez |
a09598 |
box.x2 += width;
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
box.x1 += width;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.y1 = dst->y + y - top;
|
|
Carlos Lopez |
a09598 |
box.y2 = dst->y + y + bot;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("imageglyph end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
|
|
Carlos Lopez |
a09598 |
int x, int y, unsigned int nglyph,
|
|
Carlos Lopez |
a09598 |
CharInfoPtr *ppci, pointer pglyphBase)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("polyglyph start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (nglyph > 0) {
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* ugh */
|
|
Carlos Lopez |
a09598 |
box.x1 = dst->x + x + ppci[0]->metrics.leftSideBearing;
|
|
Carlos Lopez |
a09598 |
box.x2 = dst->x + x + ppci[nglyph - 1]->metrics.rightSideBearing;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(nglyph > 1) {
|
|
Carlos Lopez |
a09598 |
int width = 0;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while(--nglyph) {
|
|
Carlos Lopez |
a09598 |
width += (*ppci)->metrics.characterWidth;
|
|
Carlos Lopez |
a09598 |
ppci++;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(width > 0) box.x2 += width;
|
|
Carlos Lopez |
a09598 |
else box.x1 += width;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
|
|
Carlos Lopez |
a09598 |
box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("polyglyph end\n");
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* changed area is in dest */
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
RootlessPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
|
|
Carlos Lopez |
a09598 |
int dx, int dy, int xOrg, int yOrg)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
BoxRec box;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GC_SKIP_ROOT (dst);
|
|
Carlos Lopez |
a09598 |
GCOP_UNWRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("push pixels start\n");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessStartDrawing((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
box.x1 = xOrg + dst->x;
|
|
Carlos Lopez |
a09598 |
box.x2 = box.x1 + dx;
|
|
Carlos Lopez |
a09598 |
box.y1 = yOrg + dst->y;
|
|
Carlos Lopez |
a09598 |
box.y2 = box.y1 + dy;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
TRIM_BOX(box, pGC);
|
|
Carlos Lopez |
a09598 |
if(BOX_NOT_EMPTY(box))
|
|
Carlos Lopez |
a09598 |
RootlessDamageBox ((WindowPtr) dst, &box);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
RootlessFinishedDrawing ((WindowPtr) dst);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
GCOP_WRAP(pGC);
|
|
Carlos Lopez |
a09598 |
RL_DEBUG_MSG("push pixels end\n");
|
|
Carlos Lopez |
a09598 |
}
|