From 0f834b91a4768673833ab4917e87d86c237bb1a6 Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 23 Mar 2012 10:05:55 +0100 Subject: libX11 xserver fontconfig mesa pixman xkbcomp xkeyboard-config git update 23 Mar 2012 --- xorg-server/render/miindex.c | 684 +++++++++++++++++++++---------------------- 1 file changed, 332 insertions(+), 352 deletions(-) (limited to 'xorg-server/render/miindex.c') diff --git a/xorg-server/render/miindex.c b/xorg-server/render/miindex.c index 23c871ba1..0375e8f88 100644 --- a/xorg-server/render/miindex.c +++ b/xorg-server/render/miindex.c @@ -1,352 +1,332 @@ -/* - * - * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#ifndef _MIINDEX_H_ -#define _MIINDEX_H_ - -#include "scrnintstr.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "mi.h" -#include "picturestr.h" -#include "mipict.h" -#include "colormapst.h" - -#define NUM_CUBE_LEVELS 4 -#define NUM_GRAY_LEVELS 13 - -static Bool -miBuildRenderColormap (ColormapPtr pColormap, Pixel *pixels, int *nump) -{ - int r, g, b; - unsigned short red, green, blue; - Pixel pixel; - Bool used[MI_MAX_INDEXED]; - int needed; - int policy; - int cube, gray; - int i, n; - - if (pColormap->mid != pColormap->pScreen->defColormap) - { - policy = PictureCmapPolicyAll; - } - else - { - int avail = pColormap->pVisual->ColormapEntries; - policy = PictureCmapPolicy; - if (policy == PictureCmapPolicyDefault) - { - if (avail >= 256 && (pColormap->pVisual->class|DynamicClass) == PseudoColor) - policy = PictureCmapPolicyColor; - else if (avail >= 64) - policy = PictureCmapPolicyGray; - else - policy = PictureCmapPolicyMono; - } - } - /* - * Make sure enough cells are free for the chosen policy - */ - for (;;) - { - switch (policy) { - case PictureCmapPolicyAll: - needed = 0; - break; - case PictureCmapPolicyColor: - needed = 71; - break; - case PictureCmapPolicyGray: - needed = 11; - break; - case PictureCmapPolicyMono: - default: - needed = 0; - break; - } - if (needed <= pColormap->freeRed) - break; - policy--; - } - - /* - * Compute size of cube and gray ramps - */ - cube = gray = 0; - switch (policy) { - case PictureCmapPolicyAll: - /* - * Allocate as big a cube as possible - */ - if ((pColormap->pVisual->class|DynamicClass) == PseudoColor) - { - for (cube = 1; cube * cube * cube < pColormap->pVisual->ColormapEntries; cube++) - ; - cube--; - if (cube == 1) - cube = 0; - } - else - cube = 0; - /* - * Figure out how many gray levels to use so that they - * line up neatly with the cube - */ - if (cube) - { - needed = pColormap->pVisual->ColormapEntries - (cube*cube*cube); - /* levels to fill in with */ - gray = needed / (cube - 1); - /* total levels */ - gray = (gray + 1) * (cube - 1) + 1; - } - else - gray = pColormap->pVisual->ColormapEntries; - break; - - case PictureCmapPolicyColor: - cube = NUM_CUBE_LEVELS; - /* fall through ... */ - case PictureCmapPolicyGray: - gray = NUM_GRAY_LEVELS; - break; - case PictureCmapPolicyMono: - default: - gray = 2; - break; - } - - memset (used, '\0', pColormap->pVisual->ColormapEntries * sizeof (Bool)); - for (r = 0; r < cube; r++) - for (g = 0; g < cube; g++) - for (b = 0; b < cube; b++) - { - pixel = 0; - red = (r * 65535 + (cube-1)/2) / (cube - 1); - green = (g * 65535 + (cube-1)/2) / (cube - 1); - blue = (b * 65535 + (cube-1)/2) / (cube - 1); - if (AllocColor (pColormap, &red, &green, - &blue, &pixel, 0) != Success) - return FALSE; - used[pixel] = TRUE; - } - for (g = 0; g < gray; g++) - { - pixel = 0; - red = green = blue = (g * 65535 + (gray-1)/2) / (gray - 1); - if (AllocColor (pColormap, &red, &green, &blue, &pixel, 0) != Success) - return FALSE; - used[pixel] = TRUE; - } - n = 0; - for (i = 0; i < pColormap->pVisual->ColormapEntries; i++) - if (used[i]) - pixels[n++] = i; - - *nump = n; - - return TRUE; -} - -/* 0 <= red, green, blue < 32 */ -static Pixel -FindBestColor (miIndexedPtr pIndexed, Pixel *pixels, int num, - int red, int green, int blue) -{ - Pixel best = pixels[0]; - int bestDist = 1 << 30; - int dist; - int dr, dg, db; - while (num--) - { - Pixel pixel = *pixels++; - CARD32 v = pIndexed->rgba[pixel]; - - dr = ((v >> 19) & 0x1f); - dg = ((v >> 11) & 0x1f); - db = ((v >> 3) & 0x1f); - dr = dr - red; - dg = dg - green; - db = db - blue; - dist = dr * dr + dg * dg + db * db; - if (dist < bestDist) - { - bestDist = dist; - best = pixel; - } - } - return best; -} - -/* 0 <= gray < 32768 */ -static Pixel -FindBestGray (miIndexedPtr pIndexed, Pixel *pixels, int num, int gray) -{ - Pixel best = pixels[0]; - int bestDist = 1 << 30; - int dist; - int dr; - int r; - - while (num--) - { - Pixel pixel = *pixels++; - CARD32 v = pIndexed->rgba[pixel]; - - r = v & 0xff; - r = r | (r << 8); - dr = gray - (r >> 1); - dist = dr * dr; - if (dist < bestDist) - { - bestDist = dist; - best = pixel; - } - } - return best; -} - -Bool -miInitIndexed (ScreenPtr pScreen, - PictFormatPtr pFormat) -{ - ColormapPtr pColormap = pFormat->index.pColormap; - VisualPtr pVisual = pColormap->pVisual; - miIndexedPtr pIndexed; - Pixel pixels[MI_MAX_INDEXED]; - xrgb rgb[MI_MAX_INDEXED]; - int num; - int i; - Pixel p, r, g, b; - - if (pVisual->ColormapEntries > MI_MAX_INDEXED) - return FALSE; - - if (pVisual->class & DynamicClass) - { - if (!miBuildRenderColormap (pColormap, pixels, &num)) - return FALSE; - } - else - { - num = pVisual->ColormapEntries; - for (p = 0; p < num; p++) - pixels[p] = p; - } - - pIndexed = malloc(sizeof (miIndexedRec)); - if (!pIndexed) - return FALSE; - - pFormat->index.nvalues = num; - pFormat->index.pValues = malloc(num * sizeof (xIndexValue)); - if (!pFormat->index.pValues) - { - free(pIndexed); - return FALSE; - } - - - /* - * Build mapping from pixel value to ARGB - */ - QueryColors (pColormap, num, pixels, rgb, serverClient); - for (i = 0; i < num; i++) - { - p = pixels[i]; - pFormat->index.pValues[i].pixel = p; - pFormat->index.pValues[i].red = rgb[i].red; - pFormat->index.pValues[i].green = rgb[i].green; - pFormat->index.pValues[i].blue = rgb[i].blue; - pFormat->index.pValues[i].alpha = 0xffff; - pIndexed->rgba[p] = (0xff000000 | - ((rgb[i].red & 0xff00) << 8) | - ((rgb[i].green & 0xff00) ) | - ((rgb[i].blue & 0xff00) >> 8)); - } - - /* - * Build mapping from RGB to pixel value. This could probably be - * done a bit quicker... - */ - switch (pVisual->class | DynamicClass) { - case GrayScale: - pIndexed->color = FALSE; - for (r = 0; r < 32768; r++) - pIndexed->ent[r] = FindBestGray (pIndexed, pixels, num, r); - break; - case PseudoColor: - pIndexed->color = TRUE; - p = 0; - for (r = 0; r < 32; r++) - for (g = 0; g < 32; g++) - for (b = 0; b < 32; b++) - { - pIndexed->ent[p] = FindBestColor (pIndexed, pixels, num, - r, g, b); - p++; - } - break; - } - pFormat->index.devPrivate = pIndexed; - return TRUE; -} - -void -miCloseIndexed (ScreenPtr pScreen, - PictFormatPtr pFormat) -{ - free(pFormat->index.devPrivate); - pFormat->index.devPrivate = NULL; - free(pFormat->index.pValues); - pFormat->index.pValues = NULL; -} - -void -miUpdateIndexed (ScreenPtr pScreen, - PictFormatPtr pFormat, - int ndef, - xColorItem *pdef) -{ - miIndexedPtr pIndexed = pFormat->index.devPrivate; - - if (pIndexed) - { - while (ndef--) - { - pIndexed->rgba[pdef->pixel] = (0xff000000 | - ((pdef->red & 0xff00) << 8) | - ((pdef->green & 0xff00) ) | - ((pdef->blue & 0xff00) >> 8)); - pdef++; - } - } -} - -#endif /* _MIINDEX_H_ */ +/* + * + * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#ifndef _MIINDEX_H_ +#define _MIINDEX_H_ + +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "mi.h" +#include "picturestr.h" +#include "mipict.h" +#include "colormapst.h" + +#define NUM_CUBE_LEVELS 4 +#define NUM_GRAY_LEVELS 13 + +static Bool +miBuildRenderColormap(ColormapPtr pColormap, Pixel * pixels, int *nump) +{ + int r, g, b; + unsigned short red, green, blue; + Pixel pixel; + Bool used[MI_MAX_INDEXED]; + int needed; + int policy; + int cube, gray; + int i, n; + + if (pColormap->mid != pColormap->pScreen->defColormap) { + policy = PictureCmapPolicyAll; + } + else { + int avail = pColormap->pVisual->ColormapEntries; + + policy = PictureCmapPolicy; + if (policy == PictureCmapPolicyDefault) { + if (avail >= 256 && + (pColormap->pVisual->class | DynamicClass) == PseudoColor) + policy = PictureCmapPolicyColor; + else if (avail >= 64) + policy = PictureCmapPolicyGray; + else + policy = PictureCmapPolicyMono; + } + } + /* + * Make sure enough cells are free for the chosen policy + */ + for (;;) { + switch (policy) { + case PictureCmapPolicyAll: + needed = 0; + break; + case PictureCmapPolicyColor: + needed = 71; + break; + case PictureCmapPolicyGray: + needed = 11; + break; + case PictureCmapPolicyMono: + default: + needed = 0; + break; + } + if (needed <= pColormap->freeRed) + break; + policy--; + } + + /* + * Compute size of cube and gray ramps + */ + cube = gray = 0; + switch (policy) { + case PictureCmapPolicyAll: + /* + * Allocate as big a cube as possible + */ + if ((pColormap->pVisual->class | DynamicClass) == PseudoColor) { + for (cube = 1; + cube * cube * cube < pColormap->pVisual->ColormapEntries; + cube++); + cube--; + if (cube == 1) + cube = 0; + } + else + cube = 0; + /* + * Figure out how many gray levels to use so that they + * line up neatly with the cube + */ + if (cube) { + needed = pColormap->pVisual->ColormapEntries - (cube * cube * cube); + /* levels to fill in with */ + gray = needed / (cube - 1); + /* total levels */ + gray = (gray + 1) * (cube - 1) + 1; + } + else + gray = pColormap->pVisual->ColormapEntries; + break; + + case PictureCmapPolicyColor: + cube = NUM_CUBE_LEVELS; + /* fall through ... */ + case PictureCmapPolicyGray: + gray = NUM_GRAY_LEVELS; + break; + case PictureCmapPolicyMono: + default: + gray = 2; + break; + } + + memset(used, '\0', pColormap->pVisual->ColormapEntries * sizeof(Bool)); + for (r = 0; r < cube; r++) + for (g = 0; g < cube; g++) + for (b = 0; b < cube; b++) { + pixel = 0; + red = (r * 65535 + (cube - 1) / 2) / (cube - 1); + green = (g * 65535 + (cube - 1) / 2) / (cube - 1); + blue = (b * 65535 + (cube - 1) / 2) / (cube - 1); + if (AllocColor(pColormap, &red, &green, + &blue, &pixel, 0) != Success) + return FALSE; + used[pixel] = TRUE; + } + for (g = 0; g < gray; g++) { + pixel = 0; + red = green = blue = (g * 65535 + (gray - 1) / 2) / (gray - 1); + if (AllocColor(pColormap, &red, &green, &blue, &pixel, 0) != Success) + return FALSE; + used[pixel] = TRUE; + } + n = 0; + for (i = 0; i < pColormap->pVisual->ColormapEntries; i++) + if (used[i]) + pixels[n++] = i; + + *nump = n; + + return TRUE; +} + +/* 0 <= red, green, blue < 32 */ +static Pixel +FindBestColor(miIndexedPtr pIndexed, Pixel * pixels, int num, + int red, int green, int blue) +{ + Pixel best = pixels[0]; + int bestDist = 1 << 30; + int dist; + int dr, dg, db; + + while (num--) { + Pixel pixel = *pixels++; + CARD32 v = pIndexed->rgba[pixel]; + + dr = ((v >> 19) & 0x1f); + dg = ((v >> 11) & 0x1f); + db = ((v >> 3) & 0x1f); + dr = dr - red; + dg = dg - green; + db = db - blue; + dist = dr * dr + dg * dg + db * db; + if (dist < bestDist) { + bestDist = dist; + best = pixel; + } + } + return best; +} + +/* 0 <= gray < 32768 */ +static Pixel +FindBestGray(miIndexedPtr pIndexed, Pixel * pixels, int num, int gray) +{ + Pixel best = pixels[0]; + int bestDist = 1 << 30; + int dist; + int dr; + int r; + + while (num--) { + Pixel pixel = *pixels++; + CARD32 v = pIndexed->rgba[pixel]; + + r = v & 0xff; + r = r | (r << 8); + dr = gray - (r >> 1); + dist = dr * dr; + if (dist < bestDist) { + bestDist = dist; + best = pixel; + } + } + return best; +} + +Bool +miInitIndexed(ScreenPtr pScreen, PictFormatPtr pFormat) +{ + ColormapPtr pColormap = pFormat->index.pColormap; + VisualPtr pVisual = pColormap->pVisual; + miIndexedPtr pIndexed; + Pixel pixels[MI_MAX_INDEXED]; + xrgb rgb[MI_MAX_INDEXED]; + int num; + int i; + Pixel p, r, g, b; + + if (pVisual->ColormapEntries > MI_MAX_INDEXED) + return FALSE; + + if (pVisual->class & DynamicClass) { + if (!miBuildRenderColormap(pColormap, pixels, &num)) + return FALSE; + } + else { + num = pVisual->ColormapEntries; + for (p = 0; p < num; p++) + pixels[p] = p; + } + + pIndexed = malloc(sizeof(miIndexedRec)); + if (!pIndexed) + return FALSE; + + pFormat->index.nvalues = num; + pFormat->index.pValues = malloc(num * sizeof(xIndexValue)); + if (!pFormat->index.pValues) { + free(pIndexed); + return FALSE; + } + + /* + * Build mapping from pixel value to ARGB + */ + QueryColors(pColormap, num, pixels, rgb, serverClient); + for (i = 0; i < num; i++) { + p = pixels[i]; + pFormat->index.pValues[i].pixel = p; + pFormat->index.pValues[i].red = rgb[i].red; + pFormat->index.pValues[i].green = rgb[i].green; + pFormat->index.pValues[i].blue = rgb[i].blue; + pFormat->index.pValues[i].alpha = 0xffff; + pIndexed->rgba[p] = (0xff000000 | + ((rgb[i].red & 0xff00) << 8) | + ((rgb[i].green & 0xff00)) | + ((rgb[i].blue & 0xff00) >> 8)); + } + + /* + * Build mapping from RGB to pixel value. This could probably be + * done a bit quicker... + */ + switch (pVisual->class | DynamicClass) { + case GrayScale: + pIndexed->color = FALSE; + for (r = 0; r < 32768; r++) + pIndexed->ent[r] = FindBestGray(pIndexed, pixels, num, r); + break; + case PseudoColor: + pIndexed->color = TRUE; + p = 0; + for (r = 0; r < 32; r++) + for (g = 0; g < 32; g++) + for (b = 0; b < 32; b++) { + pIndexed->ent[p] = FindBestColor(pIndexed, pixels, num, + r, g, b); + p++; + } + break; + } + pFormat->index.devPrivate = pIndexed; + return TRUE; +} + +void +miCloseIndexed(ScreenPtr pScreen, PictFormatPtr pFormat) +{ + free(pFormat->index.devPrivate); + pFormat->index.devPrivate = NULL; + free(pFormat->index.pValues); + pFormat->index.pValues = NULL; +} + +void +miUpdateIndexed(ScreenPtr pScreen, + PictFormatPtr pFormat, int ndef, xColorItem * pdef) +{ + miIndexedPtr pIndexed = pFormat->index.devPrivate; + + if (pIndexed) { + while (ndef--) { + pIndexed->rgba[pdef->pixel] = (0xff000000 | + ((pdef->red & 0xff00) << 8) | + ((pdef->green & 0xff00)) | + ((pdef->blue & 0xff00) >> 8)); + pdef++; + } + } +} + +#endif /* _MIINDEX_H_ */ -- cgit v1.2.3