colxlate.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /**
  2. * @file
  3. * @brief function colorxlate (one of many) for gvcolor.c
  4. */
  5. /*************************************************************************
  6. * Copyright (c) 2011 AT&T Intellectual Property
  7. * All rights reserved. This program and the accompanying materials
  8. * are made available under the terms of the Eclipse Public License v1.0
  9. * which accompanies this distribution, and is available at
  10. * https://www.eclipse.org/legal/epl-v10.html
  11. *
  12. * Contributors: Details at https://graphviz.org
  13. *************************************************************************/
  14. #include <cgraph/gv_ctype.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #include <ctype.h>
  19. #include <util/agxbuf.h>
  20. typedef struct {
  21. char *name;
  22. unsigned char h, s, b;
  23. } hsbcolor_t;
  24. #include "colortbl.h"
  25. #include "colorxlate.h"
  26. static void canoncolor(const char *orig, agxbuf *out) {
  27. char c;
  28. while ((c = *orig++)) {
  29. if (!gv_isalnum(c))
  30. continue;
  31. agxbputc(out, (char)tolower(c));
  32. }
  33. }
  34. static int colorcmpf(const void *a0, const void *a1)
  35. {
  36. const hsbcolor_t *p1 = a1;
  37. return strcmp(a0, p1->name);
  38. }
  39. void colorxlate(char *str, agxbuf *buf) {
  40. static hsbcolor_t *last;
  41. agxbuf canon_buf = {0};
  42. const char *canon = NULL;
  43. if (last == NULL || strcmp(last->name, str)) {
  44. canoncolor(str, &canon_buf);
  45. canon = agxbuse(&canon_buf);
  46. last = bsearch(canon, color_lib, sizeof(color_lib) / sizeof(hsbcolor_t),
  47. sizeof(color_lib[0]), colorcmpf);
  48. }
  49. if (last == NULL) {
  50. if (!gv_isdigit(canon[0])) {
  51. fprintf(stderr, "warning: %s is not a known color\n", str);
  52. agxbput(buf, str);
  53. } else
  54. for (const char *p = str; *p != '\0'; ++p)
  55. agxbputc(buf, *p == ',' ? ' ' : *p);
  56. } else
  57. agxbprint(buf, "%.3f %.3f %.3f", ((double) last->h) / 255,
  58. ((double) last->s) / 255, ((double) last->b) / 255);
  59. agxbfree(&canon_buf);
  60. }