summaryrefslogtreecommitdiff
path: root/support/dktools/plptcol.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/plptcol.ctr
Initial commit
Diffstat (limited to 'support/dktools/plptcol.ctr')
-rw-r--r--support/dktools/plptcol.ctr295
1 files changed, 295 insertions, 0 deletions
diff --git a/support/dktools/plptcol.ctr b/support/dktools/plptcol.ctr
new file mode 100644
index 0000000000..c923979636
--- /dev/null
+++ b/support/dktools/plptcol.ctr
@@ -0,0 +1,295 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Dynamically allocate new color structure.
+ @param name Color name.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+ @return Pointer to new structure on success, NULL on error.
+*/
+plpt_named_color_t *
+plptcolor_new(char const *name, double r, double g, double b, dk3_app_t *app);
+
+/** Compare two named colors.
+ @param l Left color.
+ @param r Right color.
+ @param cr Comparison criteria (0=name).
+ @return Comparison result.
+*/
+int
+plptcolor_compare(void const *l, void const *r, int cr);
+
+/** Destroy color structure, release memory.
+ @param ptr Color structure to destroy.
+*/
+void
+plptcolor_delete(plpt_named_color_t *ptr);
+
+/** Find color information.
+ @param job Job structure.
+ @param txt LaTeX color specification, i.e. "brown!80!blue",
+ modified during analysis.
+ @param r Pointer to red result variable.
+ @param g Pointer to green result variable.
+ @param b Pointer to blue result variable.
+*/
+int
+plptcol_get_color(
+ plpdftex_job_t *job,
+ char *txt,
+ double *r,
+ double *g,
+ double *b
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "plpdftex.h"
+
+
+
+$!trace-include
+
+
+
+void
+plptcolor_delete(plpt_named_color_t *ptr)
+{
+ if (ptr) {
+ dk3_release(ptr->name);
+ dk3_delete(ptr);
+ }
+}
+
+
+
+plpt_named_color_t *
+plptcolor_new(char const *name, double r, double g, double b, dk3_app_t *app)
+{
+ plpt_named_color_t *back = NULL;
+ if (name) {
+ back = dk3_new_app(plpt_named_color_t,1,app);
+ if (back) {
+ back->r = r;
+ back->g = g;
+ back->b = b;
+ back->name = dk3str_c8_dup_app(name, app);
+ if (!(back->name)) {
+ dk3_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+plptcolor_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ plpt_named_color_t *pl;
+ plpt_named_color_t *pr;
+
+ if (l) {
+ if (r) {
+ pl = (plpt_named_color_t *)l;
+ pr = (plpt_named_color_t *)r;
+ switch(cr) {
+ case 1: {
+ if (pl->name) {
+ back = dk3str_c8_cmp(pl->name, (char *)pr);
+ if(-1 > back) back = -1;
+ if( 1 < back) back = 1;
+ } else back = -1;
+ } break;
+ default: {
+ if (pl->name) {
+ if (pr->name) {
+ back = dk3str_c8_cmp(pl->name, pr->name);
+ if(-1 > back) back = -1;
+ if( 1 < back) back = 1;
+ } else back = 1;
+ } else {
+ if (pr->name) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if (r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Predefined colors.
+*/
+static plpt_named_color_t const plptc_predefined_colors[] = {
+ { "white", 1.0, 1.0, 1.0 },
+ { "black", 0.0, 0.0, 0.0 },
+ { "red", 1.0, 0.0, 0.0 },
+ { "green", 0.0, 1.0, 0.0 },
+ { "blue", 0.0, 0.0, 1.0 },
+ { "cyan", 0.0, 1.0, 1.0 },
+ { "magenta", 1.0, 0.0, 1.0 },
+ { "yellow", 1.0, 1.0, 0.0 },
+ { "gray", 0.5, 0.5, 0.5 },
+ { "lightgray", 0.75, 0.75, 0.75 },
+ { "darkgray", 0.25, 0.25, 0.25 },
+ { "brown", 0.75, 0.5 , 0.25 },
+ { "lime", 0.75, 1.0 , 0.0 },
+ { "olive", 0.5 , 0.5 , 0.0 },
+ { "orange", 1.0 , 0.5 , 0.0 },
+ { "pink", 1.0 , 0.75, 0.75 },
+ { "purple", 0.75, 0.0 , 0.25 },
+ { "teal", 0.00, 0.5 , 0.5 },
+ { "violet", 0.5 , 0.0 , 0.5 }
+};
+
+/** Number of predefined colors.
+*/
+static size_t const sz_plptc_predefined_colors =
+sizeof(plptc_predefined_colors)/sizeof(plpt_named_color_t);
+
+
+
+/** Find a named color.
+ @param job Job structure.
+ @param txt Color name.
+ @return Pointer to plpt_named_color_t on success, NULL on error.
+*/
+static
+plpt_named_color_t const *
+plptcol_find_color(plpdftex_job_t *job, char const *txt)
+{
+ plpt_named_color_t const *back = NULL;
+ size_t i;
+
+ for (i = 0; i < sz_plptc_predefined_colors; i++) {
+ if (0 == strcmp(txt, plptc_predefined_colors[i].name)) {
+ back = &(plptc_predefined_colors[i]);
+ }
+ }
+ if (NULL == back) {
+ back = (plpt_named_color_t *)dk3sto_it_find_like(
+ job->sico, txt, 1
+ );
+ }
+ return back;
+}
+
+
+
+int
+plptcol_get_color(
+ plpdftex_job_t *job,
+ char *txt,
+ double *r,
+ double *g,
+ double *b
+)
+{
+ plpt_named_color_t const *cptr = NULL;
+ char *stt = NULL; /* Start of text */
+ char *per = NULL; /* Percentage value as text */
+ char *bgc = NULL; /* Background color */
+ char *npt = NULL; /* Next pointer */
+ double rres = 0.0; /* Result value for red */
+ double gres = 0.0; /* Result value for green */
+ double bres = 0.0; /* Result value for blue */
+ double bgr = 0.0; /* Background red */
+ double bgg = 0.0; /* Background green */
+ double bgb = 0.0; /* Background blue */
+ double f = 1.0; /* Factor */
+ int back = 0; /* Function result */
+ $? "+ plptcol_get_color \"%!8s\"", TR_8STR(txt)
+ /* Check arguments.
+ */
+ if ((NULL == r) || (NULL == g) || (NULL == b)) { $? "! r, g, b"
+ goto finished;
+ }
+ if ((NULL == job) || (NULL == txt)) { $? "! job, txt"
+ goto cleanup;
+ }
+
+ /* Scan first color component.
+ */
+ stt = txt;
+ dk3str_c8_chomp(stt, NULL);
+ per = strchr(stt, '!');
+ if (NULL != per) { *(per++) = '\0'; }
+ cptr = plptcol_find_color(job, txt);
+ if (NULL == cptr) { $? "! color not found"
+ /* ##### ERROR: Color not found! */
+ goto cleanup;
+ }
+ rres = cptr->r; $? ". r = %lg", rres
+ gres = cptr->g; $? ". g = %lg", gres
+ bres = cptr->b; $? ". b = %lg", bres
+
+ /* Mix against further components.
+ */
+ while (NULL != per) {
+ npt = NULL;
+ bgc = strchr(per, '!');
+ if (NULL != bgc) {
+ *(bgc++) = '\0';
+ npt = strchr(bgc, '!');
+ if (NULL != npt) {
+ *(npt++) = '\0';
+ }
+ }
+ if (0 == dk3ma_d_from_c8_string(&f, per, NULL)) {
+ /* ##### ERROR: Not a number */ $? "! not a number"
+ goto cleanup;
+ }
+ if ((0.0 > f) || (100.0 < f)) { $? "! out of range"
+ /* ##### ERROR: Out of range */
+ goto cleanup;
+ }
+ f = f / 100.0;
+ bgr = bgg = bgb = 1.0;
+ if (bgc) {
+ cptr = plptcol_find_color(job, txt);
+ if (NULL == cptr) {
+ /* ##### ERROR: Color not found */
+ goto cleanup;
+ }
+ bgr = cptr->r; bgg = cptr->g; bgb = cptr->b;
+ }
+ rres = f * rres + (1.0 - f) * bgr; $? ". r = %lg", rres
+ gres = f * gres + (1.0 - f) * bgg; $? ". g = %lg", gres
+ bres = f * bres + (1.0 - f) * bgb; $? ". b = %lg", bres
+ per = npt;
+ }
+ back = 1; $? ". success"
+
+ /* Transfer results and return.
+ */
+ cleanup:
+ *r = rres; *g = gres; *b = bres;
+ finished:
+ $? "- plptcol_get_color %d rgb=(%lg %lg %lg)", back, rres, gres, bres
+ return back;
+}
+
+