⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xs_colors.c

📁 linux下的flash播放器源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz@jwz.org> * * 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.  No representations are made about the suitability of this * software for any purpose.  It is provided "as is" without express or  * implied warranty. *//* This file contains some utility routines for randomly picking the colors   to hack the screen with. */#include <stdlib.h>#include <stdio.h>#include <math.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/Xos.h>#include <X11/Xresource.h>#include "xs_visual.h"#include "xs_yarandom.h"#include "xs_hsv.h"#include "xs_colors.h"/* extern char *progname; */voidfree_colors(Display *dpy, Colormap cmap, XColor *colors, int ncolors){  int i;  if (ncolors > 0)    {      unsigned long *pixels = (unsigned long *)	malloc(sizeof(*pixels) * ncolors);      for (i = 0; i < ncolors; i++)	pixels[i] = colors[i].pixel;      XFreeColors (dpy, cmap, pixels, ncolors, 0L);      free(pixels);    }}voidallocate_writable_colors (Display *dpy, Colormap cmap,			  unsigned long *pixels, int *ncolorsP){  int desired = *ncolorsP;  int got = 0;  int requested = desired;  unsigned long *new_pixels = pixels;  *ncolorsP = 0;  while (got < desired	 && requested > 0)    {      if (desired - got < requested)	requested = desired - got;      if (XAllocColorCells (dpy, cmap, False, 0, 0, new_pixels, requested))	{	  /* Got all the pixels we asked for. */	  new_pixels += requested;	  got += requested;	}      else	{	  /* We didn't get all/any of the pixels we asked for.  This time, ask	     for half as many.  (If we do get all that we ask for, we ask for	     the same number again next time, so we only do O(log(n)) server	     roundtrips.)	  */	  requested = requested / 2;	}    }  *ncolorsP += got;}voidmake_color_ramp (Display *dpy, Colormap cmap,		 int h1, double s1, double v1,   /* 0-360, 0-1.0, 0-1.0 */		 int h2, double s2, double v2,   /* 0-360, 0-1.0, 0-1.0 */		 XColor *colors, int *ncolorsP,		 Bool closed_p,		 Bool allocate_p,		 Bool writable_p){  int i;  int ncolors = *ncolorsP;  double dh, ds, dv;		/* deltas */ AGAIN:  memset (colors, 0, (*ncolorsP) * sizeof(*colors));  if (closed_p)    ncolors = (ncolors / 2) + 1;  /* Note: unlike other routines in this module, this function assumes that     if h1 and h2 are more than 180 degrees apart, then the desired direction     is always from h1 to h2 (rather than the shorter path.)  make_uniform     depends on this.   */  dh = ((double)h2 - (double)h1) / ncolors;  ds = (s2 - s1) / ncolors;  dv = (v2 - v1) / ncolors;  for (i = 0; i < ncolors; i++)    {      colors[i].flags = DoRed|DoGreen|DoBlue;      hsv_to_rgb ((int) (h1 + (i*dh)), (s1 + (i*ds)), (v1 + (i*dv)),		  &colors[i].red, &colors[i].green, &colors[i].blue);    }  if (closed_p)    for (i = ncolors; i < *ncolorsP; i++)      colors[i] = colors[(*ncolorsP)-i];  if (!allocate_p)    return;  if (writable_p)    {      unsigned long *pixels = (unsigned long *)	malloc(sizeof(*pixels) * ((*ncolorsP) + 1));      /* allocate_writable_colors() won't do here, because we need exactly this	 number of cells, or the color sequence we've chosen won't fit. */      if (! XAllocColorCells(dpy, cmap, False, 0, 0, pixels, *ncolorsP))	{	  free(pixels);	  goto FAIL;	}      for (i = 0; i < *ncolorsP; i++)	colors[i].pixel = pixels[i];      free (pixels);      XStoreColors (dpy, cmap, colors, *ncolorsP);    }  else    {      for (i = 0; i < *ncolorsP; i++)	{	  XColor color;	  color = colors[i];	  if (XAllocColor (dpy, cmap, &color))	    {	      colors[i].pixel = color.pixel;	    }	  else	    {	      free_colors (dpy, cmap, colors, i);	      goto FAIL;	    }	}    }  return; FAIL:  /* we weren't able to allocate all the colors we wanted;     decrease the requested number and try again.   */  ncolors = (ncolors > 170 ? ncolors - 20 :	     ncolors > 100 ? ncolors - 10 :	     ncolors >  75 ? ncolors -  5 :	     ncolors >  25 ? ncolors -  3 :	     ncolors >  10 ? ncolors -  2 :	     ncolors >   2 ? ncolors -  1 :	     0);  *ncolorsP = ncolors;  if (ncolors > 0)    goto AGAIN;}#define MAXPOINTS 50	/* yeah, so I'm lazy */static voidmake_color_path (Display *dpy, Colormap cmap,		 int npoints, int *h, double *s, double *v,		 XColor *colors, int *ncolorsP,		 Bool allocate_p,		 Bool writable_p){  int i, j, k;  int total_ncolors = *ncolorsP;  int ncolors[MAXPOINTS];  /* number of pixels per edge */  double dh[MAXPOINTS];    /* distance between pixels, per edge (0 - 360.0) */  double ds[MAXPOINTS];    /* distance between pixels, per edge (0 - 1.0) */  double dv[MAXPOINTS];    /* distance between pixels, per edge (0 - 1.0) */  if (npoints == 0)    {      *ncolorsP = 0;      return;    }  else if (npoints == 2)	/* using make_color_ramp() will be faster */    {      make_color_ramp (dpy, cmap,		       h[0], s[0], v[0], h[1], s[1], v[1],		       colors, ncolorsP,		       True,  /* closed_p */		       allocate_p, writable_p);      return;    }  else if (npoints >= MAXPOINTS)    {      npoints = MAXPOINTS-1;    } AGAIN:  {    double DH[MAXPOINTS];	/* Distance between H values in the shortest				   direction around the circle, that is, the				   distance between 10 and 350 is 20.				   (Range is 0 - 360.0.)				*/    double edge[MAXPOINTS];	/* lengths of edges in unit HSV space. */    double ratio[MAXPOINTS];	/* proportions of the edges (total 1.0) */    double circum = 0;    double one_point_oh = 0;	/* (debug) */    for (i = 0; i < npoints; i++)      {	int j = (i+1) % npoints;	double d = ((double) (h[i] - h[j])) / 360;	if (d < 0) d = -d;	if (d > 0.5) d = 0.5 - (d - 0.5);	DH[i] = d;      }    for (i = 0; i < npoints; i++)      {	int j = (i+1) % npoints;	edge[i] = sqrt((DH[i] * DH[j]) +		       ((s[j] - s[i]) * (s[j] - s[i])) +		       ((v[j] - v[i]) * (v[j] - v[i])));	circum += edge[i];      }#ifdef DEBUG    fprintf(stderr, "\ncolors:");    for (i=0; i < npoints; i++)      fprintf(stderr, " (%d, %.3f, %.3f)", h[i], s[i], v[i]);    fprintf(stderr, "\nlengths:");    for (i=0; i < npoints; i++)      fprintf(stderr, " %.3f", edge[i]);#endif /* DEBUG */    if (circum < 0.0001)      goto FAIL;    for (i = 0; i < npoints; i++)      {	ratio[i] = edge[i] / circum;	one_point_oh += ratio[i];      }#ifdef DEBUG    fprintf(stderr, "\nratios:");    for (i=0; i < npoints; i++)      fprintf(stderr, " %.3f", ratio[i]);#endif /* DEBUG */    if (one_point_oh < 0.99999 || one_point_oh > 1.00001)      abort();    /* space the colors evenly along the circumference -- that means that the       number of pixels on a edge is proportional to the length of that edge       (relative to the lengths of the other edges.)     */    for (i = 0; i < npoints; i++)      ncolors[i] = total_ncolors * ratio[i];#ifdef DEBUG    fprintf(stderr, "\npixels:");    for (i=0; i < npoints; i++)      fprintf(stderr, " %d", ncolors[i]);    fprintf(stderr, "  (%d)\n", total_ncolors);#endif /* DEBUG */    for (i = 0; i < npoints; i++)      {	int j = (i+1) % npoints;	if (ncolors[i] > 0)	  {	    dh[i] = 360 * (DH[i] / ncolors[i]);	    ds[i] = (s[j] - s[i]) / ncolors[i];	    dv[i] = (v[j] - v[i]) / ncolors[i];	  }      }  }  memset (colors, 0, (*ncolorsP) * sizeof(*colors));  k = 0;  for (i = 0; i < npoints; i++)    {      int distance, direction;      distance = h[(i+1) % npoints] - h[i];      direction = (distance >= 0 ? -1 : 1);      if (distance > 180)	distance = 180 - (distance - 180);      else if (distance < -180)	distance = -(180 - ((-distance) - 180));      else	direction = -direction;#ifdef DEBUG      fprintf (stderr, "point %d: %3d %.2f %.2f\n",	       i, h[i], s[i], v[i]);      fprintf(stderr, "  h[i]=%d  dh[i]=%.2f  ncolors[i]=%d\n",	      h[i], dh[i], ncolors[i]);#endif /* DEBUG */      for (j = 0; j < ncolors[i]; j++, k++)	{	  double hh = (h[i] + (j * dh[i] * direction));	  if (hh < 0) hh += 360;	  else if (hh > 360) hh -= 0;	  colors[k].flags = DoRed|DoGreen|DoBlue;	  hsv_to_rgb ((int)		      hh,		      (s[i] + (j * ds[i])),		      (v[i] + (j * dv[i])),		      &colors[k].red, &colors[k].green, &colors[k].blue);#ifdef DEBUG	  fprintf (stderr, "point %d+%d: %.2f %.2f %.2f  %04X %04X %04X\n",		   i, j,		   hh,		   (s[i] + (j * ds[i])),		   (v[i] + (j * dv[i])),		   colors[k].red, colors[k].green, colors[k].blue);#endif /* DEBUG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -