1706f2543Smrg/* 2706f2543Smrg * 3706f2543Smrg * Copyright © 1999 Keith Packard 4706f2543Smrg * 5706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 6706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 7706f2543Smrg * the above copyright notice appear in all copies and that both that 8706f2543Smrg * copyright notice and this permission notice appear in supporting 9706f2543Smrg * documentation, and that the name of Keith Packard not be used in 10706f2543Smrg * advertising or publicity pertaining to distribution of the software without 11706f2543Smrg * specific, written prior permission. Keith Packard makes no 12706f2543Smrg * representations about the suitability of this software for any purpose. It 13706f2543Smrg * is provided "as is" without express or implied warranty. 14706f2543Smrg * 15706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 22706f2543Smrg */ 23706f2543Smrg 24706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 25706f2543Smrg#include <dix-config.h> 26706f2543Smrg#endif 27706f2543Smrg 28706f2543Smrg#include "scrnintstr.h" 29706f2543Smrg#include "gcstruct.h" 30706f2543Smrg#include "pixmapstr.h" 31706f2543Smrg#include "windowstr.h" 32706f2543Smrg#include "mi.h" 33706f2543Smrg#include "picturestr.h" 34706f2543Smrg#include "mipict.h" 35706f2543Smrg 36706f2543Smrg#ifndef __GNUC__ 37706f2543Smrg#define __inline 38706f2543Smrg#endif 39706f2543Smrg 40706f2543Smrgint 41706f2543SmrgmiCreatePicture (PicturePtr pPicture) 42706f2543Smrg{ 43706f2543Smrg return Success; 44706f2543Smrg} 45706f2543Smrg 46706f2543Smrgvoid 47706f2543SmrgmiDestroyPicture (PicturePtr pPicture) 48706f2543Smrg{ 49706f2543Smrg if (pPicture->freeCompClip) 50706f2543Smrg RegionDestroy(pPicture->pCompositeClip); 51706f2543Smrg} 52706f2543Smrg 53706f2543Smrgvoid 54706f2543SmrgmiDestroyPictureClip (PicturePtr pPicture) 55706f2543Smrg{ 56706f2543Smrg switch (pPicture->clientClipType) { 57706f2543Smrg case CT_NONE: 58706f2543Smrg return; 59706f2543Smrg case CT_PIXMAP: 60706f2543Smrg (*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip)); 61706f2543Smrg break; 62706f2543Smrg default: 63706f2543Smrg /* 64706f2543Smrg * we know we'll never have a list of rectangles, since ChangeClip 65706f2543Smrg * immediately turns them into a region 66706f2543Smrg */ 67706f2543Smrg RegionDestroy(pPicture->clientClip); 68706f2543Smrg break; 69706f2543Smrg } 70706f2543Smrg pPicture->clientClip = NULL; 71706f2543Smrg pPicture->clientClipType = CT_NONE; 72706f2543Smrg} 73706f2543Smrg 74706f2543Smrgint 75706f2543SmrgmiChangePictureClip (PicturePtr pPicture, 76706f2543Smrg int type, 77706f2543Smrg pointer value, 78706f2543Smrg int n) 79706f2543Smrg{ 80706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 81706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 82706f2543Smrg pointer clientClip; 83706f2543Smrg int clientClipType; 84706f2543Smrg 85706f2543Smrg switch (type) { 86706f2543Smrg case CT_PIXMAP: 87706f2543Smrg /* convert the pixmap to a region */ 88706f2543Smrg clientClip = (pointer) BitmapToRegion(pScreen, (PixmapPtr) value); 89706f2543Smrg if (!clientClip) 90706f2543Smrg return BadAlloc; 91706f2543Smrg clientClipType = CT_REGION; 92706f2543Smrg (*pScreen->DestroyPixmap) ((PixmapPtr) value); 93706f2543Smrg break; 94706f2543Smrg case CT_REGION: 95706f2543Smrg clientClip = value; 96706f2543Smrg clientClipType = CT_REGION; 97706f2543Smrg break; 98706f2543Smrg case CT_NONE: 99706f2543Smrg clientClip = 0; 100706f2543Smrg clientClipType = CT_NONE; 101706f2543Smrg break; 102706f2543Smrg default: 103706f2543Smrg clientClip = (pointer) RegionFromRects(n, 104706f2543Smrg (xRectangle *) value, 105706f2543Smrg type); 106706f2543Smrg if (!clientClip) 107706f2543Smrg return BadAlloc; 108706f2543Smrg clientClipType = CT_REGION; 109706f2543Smrg free(value); 110706f2543Smrg break; 111706f2543Smrg } 112706f2543Smrg (*ps->DestroyPictureClip) (pPicture); 113706f2543Smrg pPicture->clientClip = clientClip; 114706f2543Smrg pPicture->clientClipType = clientClipType; 115706f2543Smrg pPicture->stateChanges |= CPClipMask; 116706f2543Smrg return Success; 117706f2543Smrg} 118706f2543Smrg 119706f2543Smrgvoid 120706f2543SmrgmiChangePicture (PicturePtr pPicture, 121706f2543Smrg Mask mask) 122706f2543Smrg{ 123706f2543Smrg return; 124706f2543Smrg} 125706f2543Smrg 126706f2543Smrgvoid 127706f2543SmrgmiValidatePicture (PicturePtr pPicture, 128706f2543Smrg Mask mask) 129706f2543Smrg{ 130706f2543Smrg DrawablePtr pDrawable = pPicture->pDrawable; 131706f2543Smrg 132706f2543Smrg if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) || 133706f2543Smrg (pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS))) 134706f2543Smrg { 135706f2543Smrg if (pDrawable->type == DRAWABLE_WINDOW) 136706f2543Smrg { 137706f2543Smrg WindowPtr pWin = (WindowPtr) pDrawable; 138706f2543Smrg RegionPtr pregWin; 139706f2543Smrg Bool freeTmpClip, freeCompClip; 140706f2543Smrg 141706f2543Smrg if (pPicture->subWindowMode == IncludeInferiors) 142706f2543Smrg { 143706f2543Smrg pregWin = NotClippedByChildren(pWin); 144706f2543Smrg freeTmpClip = TRUE; 145706f2543Smrg } 146706f2543Smrg else 147706f2543Smrg { 148706f2543Smrg pregWin = &pWin->clipList; 149706f2543Smrg freeTmpClip = FALSE; 150706f2543Smrg } 151706f2543Smrg freeCompClip = pPicture->freeCompClip; 152706f2543Smrg 153706f2543Smrg /* 154706f2543Smrg * if there is no client clip, we can get by with just keeping the 155706f2543Smrg * pointer we got, and remembering whether or not should destroy 156706f2543Smrg * (or maybe re-use) it later. this way, we avoid unnecessary 157706f2543Smrg * copying of regions. (this wins especially if many clients clip 158706f2543Smrg * by children and have no client clip.) 159706f2543Smrg */ 160706f2543Smrg if (pPicture->clientClipType == CT_NONE) 161706f2543Smrg { 162706f2543Smrg if (freeCompClip) 163706f2543Smrg RegionDestroy(pPicture->pCompositeClip); 164706f2543Smrg pPicture->pCompositeClip = pregWin; 165706f2543Smrg pPicture->freeCompClip = freeTmpClip; 166706f2543Smrg } 167706f2543Smrg else 168706f2543Smrg { 169706f2543Smrg /* 170706f2543Smrg * we need one 'real' region to put into the composite clip. if 171706f2543Smrg * pregWin the current composite clip are real, we can get rid of 172706f2543Smrg * one. if pregWin is real and the current composite clip isn't, 173706f2543Smrg * use pregWin for the composite clip. if the current composite 174706f2543Smrg * clip is real and pregWin isn't, use the current composite 175706f2543Smrg * clip. if neither is real, create a new region. 176706f2543Smrg */ 177706f2543Smrg 178706f2543Smrg RegionTranslate(pPicture->clientClip, 179706f2543Smrg pDrawable->x + pPicture->clipOrigin.x, 180706f2543Smrg pDrawable->y + pPicture->clipOrigin.y); 181706f2543Smrg 182706f2543Smrg if (freeCompClip) 183706f2543Smrg { 184706f2543Smrg RegionIntersect(pPicture->pCompositeClip, 185706f2543Smrg pregWin, pPicture->clientClip); 186706f2543Smrg if (freeTmpClip) 187706f2543Smrg RegionDestroy(pregWin); 188706f2543Smrg } 189706f2543Smrg else if (freeTmpClip) 190706f2543Smrg { 191706f2543Smrg RegionIntersect(pregWin, pregWin, pPicture->clientClip); 192706f2543Smrg pPicture->pCompositeClip = pregWin; 193706f2543Smrg } 194706f2543Smrg else 195706f2543Smrg { 196706f2543Smrg pPicture->pCompositeClip = RegionCreate(NullBox, 0); 197706f2543Smrg RegionIntersect(pPicture->pCompositeClip, 198706f2543Smrg pregWin, pPicture->clientClip); 199706f2543Smrg } 200706f2543Smrg pPicture->freeCompClip = TRUE; 201706f2543Smrg RegionTranslate(pPicture->clientClip, 202706f2543Smrg -(pDrawable->x + pPicture->clipOrigin.x), 203706f2543Smrg -(pDrawable->y + pPicture->clipOrigin.y)); 204706f2543Smrg } 205706f2543Smrg } /* end of composite clip for a window */ 206706f2543Smrg else 207706f2543Smrg { 208706f2543Smrg BoxRec pixbounds; 209706f2543Smrg 210706f2543Smrg /* XXX should we translate by drawable.x/y here ? */ 211706f2543Smrg /* If you want pixmaps in offscreen memory, yes */ 212706f2543Smrg pixbounds.x1 = pDrawable->x; 213706f2543Smrg pixbounds.y1 = pDrawable->y; 214706f2543Smrg pixbounds.x2 = pDrawable->x + pDrawable->width; 215706f2543Smrg pixbounds.y2 = pDrawable->y + pDrawable->height; 216706f2543Smrg 217706f2543Smrg if (pPicture->freeCompClip) 218706f2543Smrg { 219706f2543Smrg RegionReset(pPicture->pCompositeClip, &pixbounds); 220706f2543Smrg } 221706f2543Smrg else 222706f2543Smrg { 223706f2543Smrg pPicture->freeCompClip = TRUE; 224706f2543Smrg pPicture->pCompositeClip = RegionCreate(&pixbounds, 1); 225706f2543Smrg } 226706f2543Smrg 227706f2543Smrg if (pPicture->clientClipType == CT_REGION) 228706f2543Smrg { 229706f2543Smrg if(pDrawable->x || pDrawable->y) { 230706f2543Smrg RegionTranslate(pPicture->clientClip, 231706f2543Smrg pDrawable->x + pPicture->clipOrigin.x, 232706f2543Smrg pDrawable->y + pPicture->clipOrigin.y); 233706f2543Smrg RegionIntersect(pPicture->pCompositeClip, 234706f2543Smrg pPicture->pCompositeClip, pPicture->clientClip); 235706f2543Smrg RegionTranslate(pPicture->clientClip, 236706f2543Smrg -(pDrawable->x + pPicture->clipOrigin.x), 237706f2543Smrg -(pDrawable->y + pPicture->clipOrigin.y)); 238706f2543Smrg } else { 239706f2543Smrg RegionTranslate(pPicture->pCompositeClip, 240706f2543Smrg -pPicture->clipOrigin.x, -pPicture->clipOrigin.y); 241706f2543Smrg RegionIntersect(pPicture->pCompositeClip, 242706f2543Smrg pPicture->pCompositeClip, pPicture->clientClip); 243706f2543Smrg RegionTranslate(pPicture->pCompositeClip, 244706f2543Smrg pPicture->clipOrigin.x, pPicture->clipOrigin.y); 245706f2543Smrg } 246706f2543Smrg } 247706f2543Smrg } /* end of composite clip for pixmap */ 248706f2543Smrg } 249706f2543Smrg} 250706f2543Smrg 251706f2543Smrgint 252706f2543SmrgmiChangePictureTransform (PicturePtr pPicture, 253706f2543Smrg PictTransform *transform) 254706f2543Smrg{ 255706f2543Smrg return Success; 256706f2543Smrg} 257706f2543Smrg 258706f2543Smrgint 259706f2543SmrgmiChangePictureFilter (PicturePtr pPicture, 260706f2543Smrg int filter, 261706f2543Smrg xFixed *params, 262706f2543Smrg int nparams) 263706f2543Smrg{ 264706f2543Smrg return Success; 265706f2543Smrg} 266706f2543Smrg 267706f2543Smrg#define BOUND(v) (INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v)) 268706f2543Smrg 269706f2543Smrgstatic inline pixman_bool_t 270706f2543SmrgmiClipPictureReg (pixman_region16_t * pRegion, 271706f2543Smrg pixman_region16_t * pClip, 272706f2543Smrg int dx, 273706f2543Smrg int dy) 274706f2543Smrg{ 275706f2543Smrg if (pixman_region_n_rects(pRegion) == 1 && 276706f2543Smrg pixman_region_n_rects(pClip) == 1) 277706f2543Smrg { 278706f2543Smrg pixman_box16_t * pRbox = pixman_region_rectangles(pRegion, NULL); 279706f2543Smrg pixman_box16_t * pCbox = pixman_region_rectangles(pClip, NULL); 280706f2543Smrg int v; 281706f2543Smrg 282706f2543Smrg if (pRbox->x1 < (v = pCbox->x1 + dx)) 283706f2543Smrg pRbox->x1 = BOUND(v); 284706f2543Smrg if (pRbox->x2 > (v = pCbox->x2 + dx)) 285706f2543Smrg pRbox->x2 = BOUND(v); 286706f2543Smrg if (pRbox->y1 < (v = pCbox->y1 + dy)) 287706f2543Smrg pRbox->y1 = BOUND(v); 288706f2543Smrg if (pRbox->y2 > (v = pCbox->y2 + dy)) 289706f2543Smrg pRbox->y2 = BOUND(v); 290706f2543Smrg if (pRbox->x1 >= pRbox->x2 || 291706f2543Smrg pRbox->y1 >= pRbox->y2) 292706f2543Smrg { 293706f2543Smrg pixman_region_init (pRegion); 294706f2543Smrg } 295706f2543Smrg } 296706f2543Smrg else if (!pixman_region_not_empty (pClip)) 297706f2543Smrg return FALSE; 298706f2543Smrg else 299706f2543Smrg { 300706f2543Smrg if (dx || dy) 301706f2543Smrg pixman_region_translate (pRegion, -dx, -dy); 302706f2543Smrg if (!pixman_region_intersect (pRegion, pRegion, pClip)) 303706f2543Smrg return FALSE; 304706f2543Smrg if (dx || dy) 305706f2543Smrg pixman_region_translate(pRegion, dx, dy); 306706f2543Smrg } 307706f2543Smrg return pixman_region_not_empty(pRegion); 308706f2543Smrg} 309706f2543Smrg 310706f2543Smrgstatic __inline Bool 311706f2543SmrgmiClipPictureSrc (RegionPtr pRegion, 312706f2543Smrg PicturePtr pPicture, 313706f2543Smrg int dx, 314706f2543Smrg int dy) 315706f2543Smrg{ 316706f2543Smrg if (pPicture->clientClipType != CT_NONE) 317706f2543Smrg { 318706f2543Smrg Bool result; 319706f2543Smrg 320706f2543Smrg pixman_region_translate ( pPicture->clientClip, 321706f2543Smrg pPicture->clipOrigin.x + dx, 322706f2543Smrg pPicture->clipOrigin.y + dy); 323706f2543Smrg 324706f2543Smrg result = RegionIntersect(pRegion, pRegion, pPicture->clientClip); 325706f2543Smrg 326706f2543Smrg pixman_region_translate ( pPicture->clientClip, 327706f2543Smrg - (pPicture->clipOrigin.x + dx), 328706f2543Smrg - (pPicture->clipOrigin.y + dy)); 329706f2543Smrg 330706f2543Smrg if (!result) 331706f2543Smrg return FALSE; 332706f2543Smrg } 333706f2543Smrg return TRUE; 334706f2543Smrg} 335706f2543Smrg 336706f2543Smrgvoid 337706f2543SmrgmiCompositeSourceValidate (PicturePtr pPicture, 338706f2543Smrg INT16 x, 339706f2543Smrg INT16 y, 340706f2543Smrg CARD16 width, 341706f2543Smrg CARD16 height) 342706f2543Smrg{ 343706f2543Smrg DrawablePtr pDrawable = pPicture->pDrawable; 344706f2543Smrg ScreenPtr pScreen; 345706f2543Smrg 346706f2543Smrg if (!pDrawable) 347706f2543Smrg return; 348706f2543Smrg 349706f2543Smrg pScreen = pDrawable->pScreen; 350706f2543Smrg 351706f2543Smrg if (pScreen->SourceValidate) 352706f2543Smrg { 353706f2543Smrg if (pPicture->transform) 354706f2543Smrg { 355706f2543Smrg xPoint points[4]; 356706f2543Smrg int i; 357706f2543Smrg int xmin, ymin, xmax, ymax; 358706f2543Smrg 359706f2543Smrg#define VectorSet(i,_x,_y) { points[i].x = _x; points[i].y = _y; } 360706f2543Smrg VectorSet (0, x, y); 361706f2543Smrg VectorSet (1, x + width, y); 362706f2543Smrg VectorSet (2, x, y + height); 363706f2543Smrg VectorSet (3, x + width, y + height); 364706f2543Smrg xmin = ymin = 32767; 365706f2543Smrg xmax = ymax = -32737; 366706f2543Smrg for (i = 0; i < 4; i++) 367706f2543Smrg { 368706f2543Smrg PictVector t; 369706f2543Smrg t.vector[0] = IntToxFixed (points[i].x); 370706f2543Smrg t.vector[1] = IntToxFixed (points[i].y); 371706f2543Smrg t.vector[2] = xFixed1; 372706f2543Smrg if (pixman_transform_point (pPicture->transform, &t)) 373706f2543Smrg { 374706f2543Smrg int tx = xFixedToInt (t.vector[0]); 375706f2543Smrg int ty = xFixedToInt (t.vector[1]); 376706f2543Smrg if (tx < xmin) xmin = tx; 377706f2543Smrg if (tx > xmax) xmax = tx; 378706f2543Smrg if (ty < ymin) ymin = ty; 379706f2543Smrg if (ty > ymax) ymax = ty; 380706f2543Smrg } 381706f2543Smrg } 382706f2543Smrg x = xmin; 383706f2543Smrg y = ymin; 384706f2543Smrg width = xmax - xmin; 385706f2543Smrg height = ymax - ymin; 386706f2543Smrg } 387706f2543Smrg x += pPicture->pDrawable->x; 388706f2543Smrg y += pPicture->pDrawable->y; 389706f2543Smrg (*pScreen->SourceValidate) (pDrawable, x, y, width, height, 390706f2543Smrg pPicture->subWindowMode); 391706f2543Smrg } 392706f2543Smrg} 393706f2543Smrg 394706f2543Smrg/* 395706f2543Smrg * returns FALSE if the final region is empty. Indistinguishable from 396706f2543Smrg * an allocation failure, but rendering ignores those anyways. 397706f2543Smrg */ 398706f2543Smrg 399706f2543SmrgBool 400706f2543SmrgmiComputeCompositeRegion (RegionPtr pRegion, 401706f2543Smrg PicturePtr pSrc, 402706f2543Smrg PicturePtr pMask, 403706f2543Smrg PicturePtr pDst, 404706f2543Smrg INT16 xSrc, 405706f2543Smrg INT16 ySrc, 406706f2543Smrg INT16 xMask, 407706f2543Smrg INT16 yMask, 408706f2543Smrg INT16 xDst, 409706f2543Smrg INT16 yDst, 410706f2543Smrg CARD16 width, 411706f2543Smrg CARD16 height) 412706f2543Smrg{ 413706f2543Smrg 414706f2543Smrg int v; 415706f2543Smrg 416706f2543Smrg pRegion->extents.x1 = xDst; 417706f2543Smrg v = xDst + width; 418706f2543Smrg pRegion->extents.x2 = BOUND(v); 419706f2543Smrg pRegion->extents.y1 = yDst; 420706f2543Smrg v = yDst + height; 421706f2543Smrg pRegion->extents.y2 = BOUND(v); 422706f2543Smrg pRegion->data = 0; 423706f2543Smrg /* Check for empty operation */ 424706f2543Smrg if (pRegion->extents.x1 >= pRegion->extents.x2 || 425706f2543Smrg pRegion->extents.y1 >= pRegion->extents.y2) 426706f2543Smrg { 427706f2543Smrg pixman_region_init (pRegion); 428706f2543Smrg return FALSE; 429706f2543Smrg } 430706f2543Smrg /* clip against dst */ 431706f2543Smrg if (!miClipPictureReg (pRegion, pDst->pCompositeClip, 0, 0)) 432706f2543Smrg { 433706f2543Smrg pixman_region_fini (pRegion); 434706f2543Smrg return FALSE; 435706f2543Smrg } 436706f2543Smrg if (pDst->alphaMap) 437706f2543Smrg { 438706f2543Smrg if (!miClipPictureReg (pRegion, pDst->alphaMap->pCompositeClip, 439706f2543Smrg -pDst->alphaOrigin.x, 440706f2543Smrg -pDst->alphaOrigin.y)) 441706f2543Smrg { 442706f2543Smrg pixman_region_fini (pRegion); 443706f2543Smrg return FALSE; 444706f2543Smrg } 445706f2543Smrg } 446706f2543Smrg /* clip against src */ 447706f2543Smrg if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc)) 448706f2543Smrg { 449706f2543Smrg pixman_region_fini (pRegion); 450706f2543Smrg return FALSE; 451706f2543Smrg } 452706f2543Smrg if (pSrc->alphaMap) 453706f2543Smrg { 454706f2543Smrg if (!miClipPictureSrc (pRegion, pSrc->alphaMap, 455706f2543Smrg xDst - (xSrc - pSrc->alphaOrigin.x), 456706f2543Smrg yDst - (ySrc - pSrc->alphaOrigin.y))) 457706f2543Smrg { 458706f2543Smrg pixman_region_fini (pRegion); 459706f2543Smrg return FALSE; 460706f2543Smrg } 461706f2543Smrg } 462706f2543Smrg /* clip against mask */ 463706f2543Smrg if (pMask) 464706f2543Smrg { 465706f2543Smrg if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask)) 466706f2543Smrg { 467706f2543Smrg pixman_region_fini (pRegion); 468706f2543Smrg return FALSE; 469706f2543Smrg } 470706f2543Smrg if (pMask->alphaMap) 471706f2543Smrg { 472706f2543Smrg if (!miClipPictureSrc (pRegion, pMask->alphaMap, 473706f2543Smrg xDst - (xMask - pMask->alphaOrigin.x), 474706f2543Smrg yDst - (yMask - pMask->alphaOrigin.y))) 475706f2543Smrg { 476706f2543Smrg pixman_region_fini (pRegion); 477706f2543Smrg return FALSE; 478706f2543Smrg } 479706f2543Smrg } 480706f2543Smrg } 481706f2543Smrg 482706f2543Smrg 483706f2543Smrg miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height); 484706f2543Smrg if (pMask) 485706f2543Smrg miCompositeSourceValidate (pMask, xMask, yMask, width, height); 486706f2543Smrg 487706f2543Smrg return TRUE; 488706f2543Smrg} 489706f2543Smrg 490706f2543Smrgvoid 491706f2543SmrgmiRenderColorToPixel (PictFormatPtr format, 492706f2543Smrg xRenderColor *color, 493706f2543Smrg CARD32 *pixel) 494706f2543Smrg{ 495706f2543Smrg CARD32 r, g, b, a; 496706f2543Smrg miIndexedPtr pIndexed; 497706f2543Smrg 498706f2543Smrg switch (format->type) { 499706f2543Smrg case PictTypeDirect: 500706f2543Smrg r = color->red >> (16 - Ones (format->direct.redMask)); 501706f2543Smrg g = color->green >> (16 - Ones (format->direct.greenMask)); 502706f2543Smrg b = color->blue >> (16 - Ones (format->direct.blueMask)); 503706f2543Smrg a = color->alpha >> (16 - Ones (format->direct.alphaMask)); 504706f2543Smrg r = r << format->direct.red; 505706f2543Smrg g = g << format->direct.green; 506706f2543Smrg b = b << format->direct.blue; 507706f2543Smrg a = a << format->direct.alpha; 508706f2543Smrg *pixel = r|g|b|a; 509706f2543Smrg break; 510706f2543Smrg case PictTypeIndexed: 511706f2543Smrg pIndexed = (miIndexedPtr) (format->index.devPrivate); 512706f2543Smrg if (pIndexed->color) 513706f2543Smrg { 514706f2543Smrg r = color->red >> 11; 515706f2543Smrg g = color->green >> 11; 516706f2543Smrg b = color->blue >> 11; 517706f2543Smrg *pixel = miIndexToEnt15 (pIndexed, (r << 10) | (g << 5) | b); 518706f2543Smrg } 519706f2543Smrg else 520706f2543Smrg { 521706f2543Smrg r = color->red >> 8; 522706f2543Smrg g = color->green >> 8; 523706f2543Smrg b = color->blue >> 8; 524706f2543Smrg *pixel = miIndexToEntY24 (pIndexed, (r << 16) | (g << 8) | b); 525706f2543Smrg } 526706f2543Smrg break; 527706f2543Smrg } 528706f2543Smrg} 529706f2543Smrg 530706f2543Smrgstatic CARD16 531706f2543SmrgmiFillColor (CARD32 pixel, int bits) 532706f2543Smrg{ 533706f2543Smrg while (bits < 16) 534706f2543Smrg { 535706f2543Smrg pixel |= pixel << bits; 536706f2543Smrg bits <<= 1; 537706f2543Smrg } 538706f2543Smrg return (CARD16) pixel; 539706f2543Smrg} 540706f2543Smrg 541706f2543SmrgBool 542706f2543SmrgmiIsSolidAlpha (PicturePtr pSrc) 543706f2543Smrg{ 544706f2543Smrg ScreenPtr pScreen; 545706f2543Smrg char line[1]; 546706f2543Smrg 547706f2543Smrg if (!pSrc->pDrawable) 548706f2543Smrg return FALSE; 549706f2543Smrg 550706f2543Smrg pScreen = pSrc->pDrawable->pScreen; 551706f2543Smrg 552706f2543Smrg /* Alpha-only */ 553706f2543Smrg if (PICT_FORMAT_TYPE (pSrc->format) != PICT_TYPE_A) 554706f2543Smrg return FALSE; 555706f2543Smrg /* repeat */ 556706f2543Smrg if (!pSrc->repeat) 557706f2543Smrg return FALSE; 558706f2543Smrg /* 1x1 */ 559706f2543Smrg if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1) 560706f2543Smrg return FALSE; 561706f2543Smrg line[0] = 1; 562706f2543Smrg (*pScreen->GetImage) (pSrc->pDrawable, 0, 0, 1, 1, ZPixmap, ~0L, line); 563706f2543Smrg switch (pSrc->pDrawable->bitsPerPixel) { 564706f2543Smrg case 1: 565706f2543Smrg return (CARD8) line[0] == 1 || (CARD8) line[0] == 0x80; 566706f2543Smrg case 4: 567706f2543Smrg return (CARD8) line[0] == 0xf || (CARD8) line[0] == 0xf0; 568706f2543Smrg case 8: 569706f2543Smrg return (CARD8) line[0] == 0xff; 570706f2543Smrg default: 571706f2543Smrg return FALSE; 572706f2543Smrg } 573706f2543Smrg} 574706f2543Smrg 575706f2543Smrgvoid 576706f2543SmrgmiRenderPixelToColor (PictFormatPtr format, 577706f2543Smrg CARD32 pixel, 578706f2543Smrg xRenderColor *color) 579706f2543Smrg{ 580706f2543Smrg CARD32 r, g, b, a; 581706f2543Smrg miIndexedPtr pIndexed; 582706f2543Smrg 583706f2543Smrg switch (format->type) { 584706f2543Smrg case PictTypeDirect: 585706f2543Smrg r = (pixel >> format->direct.red) & format->direct.redMask; 586706f2543Smrg g = (pixel >> format->direct.green) & format->direct.greenMask; 587706f2543Smrg b = (pixel >> format->direct.blue) & format->direct.blueMask; 588706f2543Smrg a = (pixel >> format->direct.alpha) & format->direct.alphaMask; 589706f2543Smrg color->red = miFillColor (r, Ones (format->direct.redMask)); 590706f2543Smrg color->green = miFillColor (g, Ones (format->direct.greenMask)); 591706f2543Smrg color->blue = miFillColor (b, Ones (format->direct.blueMask)); 592706f2543Smrg color->alpha = miFillColor (a, Ones (format->direct.alphaMask)); 593706f2543Smrg break; 594706f2543Smrg case PictTypeIndexed: 595706f2543Smrg pIndexed = (miIndexedPtr) (format->index.devPrivate); 596706f2543Smrg pixel = pIndexed->rgba[pixel & (MI_MAX_INDEXED-1)]; 597706f2543Smrg r = (pixel >> 16) & 0xff; 598706f2543Smrg g = (pixel >> 8) & 0xff; 599706f2543Smrg b = (pixel ) & 0xff; 600706f2543Smrg color->red = miFillColor (r, 8); 601706f2543Smrg color->green = miFillColor (g, 8); 602706f2543Smrg color->blue = miFillColor (b, 8); 603706f2543Smrg color->alpha = 0xffff; 604706f2543Smrg break; 605706f2543Smrg } 606706f2543Smrg} 607706f2543Smrg 608706f2543SmrgBool 609706f2543SmrgmiPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) 610706f2543Smrg{ 611706f2543Smrg PictureScreenPtr ps; 612706f2543Smrg 613706f2543Smrg if (!PictureInit (pScreen, formats, nformats)) 614706f2543Smrg return FALSE; 615706f2543Smrg ps = GetPictureScreen(pScreen); 616706f2543Smrg ps->CreatePicture = miCreatePicture; 617706f2543Smrg ps->DestroyPicture = miDestroyPicture; 618706f2543Smrg ps->ChangePictureClip = miChangePictureClip; 619706f2543Smrg ps->DestroyPictureClip = miDestroyPictureClip; 620706f2543Smrg ps->ChangePicture = miChangePicture; 621706f2543Smrg ps->ValidatePicture = miValidatePicture; 622706f2543Smrg ps->InitIndexed = miInitIndexed; 623706f2543Smrg ps->CloseIndexed = miCloseIndexed; 624706f2543Smrg ps->UpdateIndexed = miUpdateIndexed; 625706f2543Smrg ps->ChangePictureTransform = miChangePictureTransform; 626706f2543Smrg ps->ChangePictureFilter = miChangePictureFilter; 627706f2543Smrg ps->RealizeGlyph = miRealizeGlyph; 628706f2543Smrg ps->UnrealizeGlyph = miUnrealizeGlyph; 629706f2543Smrg 630706f2543Smrg /* MI rendering routines */ 631706f2543Smrg ps->Composite = 0; /* requires DDX support */ 632706f2543Smrg ps->Glyphs = miGlyphs; 633706f2543Smrg ps->CompositeRects = miCompositeRects; 634706f2543Smrg ps->Trapezoids = miTrapezoids; 635706f2543Smrg ps->Triangles = miTriangles; 636706f2543Smrg ps->TriStrip = miTriStrip; 637706f2543Smrg ps->TriFan = miTriFan; 638706f2543Smrg 639706f2543Smrg ps->RasterizeTrapezoid = 0; /* requires DDX support */ 640706f2543Smrg ps->AddTraps = 0; /* requires DDX support */ 641706f2543Smrg ps->AddTriangles = 0; /* requires DDX support */ 642706f2543Smrg 643706f2543Smrg return TRUE; 644706f2543Smrg} 645