Tk Source Code

Check-in [190211c6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:implementation complete, todo: more testing
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | rfe-3503317
Files: files | file ages | folders
SHA1: 190211c67df80745831cee93055f113f95f607b7
User & Date: jan.nijtmans 2012-03-17 00:18:41
Context
2012-03-17
00:33
elimination of gray table by using calculations in stead check-in: 4ecc5287 user: jan.nijtmans tags: rfe-3503317
00:18
implementation complete, todo: more testing check-in: 190211c6 user: jan.nijtmans tags: rfe-3503317
2012-03-16
22:36
further reduction of color table to 147 entries! check-in: 7f343b6e user: jan.nijtmans tags: rfe-3503317
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to xlib/xcolors.c.

277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304







305


306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322
323
324
325
    return result;
}
#   endif
#else
#   define _strtoi64 strtoll
#endif

static int colorcmp(const char *spec, const char *pname) {
    int r;
    int c, d;
    int notequal = 0;

    do {
	d = *pname++;
	c = (*spec == ' ');
	if (c) {
	    spec++;
	}
	if ((d >= 'A') && (d <= 'Z')) {
	    d += 'a' - 'A';
	} else if (c) {
	    /* A space doesn't match a lowercase, but we don't know
	     * yet whether we should return a negative or positive
	     * number. That depends on what follows. */
	    notequal = 1;
	}
	c = *spec++;
	if ((c >= 'A') && (c <= 'Z')) {
	    c += 'a' - 'A';







	}


	r = c - d;
    } while(!r && c);
    if (!r && notequal) {
	/* Strings are equal, but difference in spacings only. We should still
	 * report not-equal, so "burly wood" is not a valid color */
	r = 1;
    }

    return r;
}

#define RED(p) ((unsigned char)(p)[28])
#define GREEN(p) ((unsigned char)(p)[29])
#define BLUE(p) ((unsigned char)(p)[30])

Status
XParseColor(
    Display *display,
    Colormap map,
    const char *spec,
    XColor *colorPtr)







|



>






|








|

>
>
>
>
>
>
>
|
>
>

|





>



|
|
|







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    return result;
}
#   endif
#else
#   define _strtoi64 strtoll
#endif

static int colorcmp(const char *spec, const char *pname, int *special) {
    int r;
    int c, d;
    int notequal = 0;
    int num = 0;
    do {
	d = *pname++;
	c = (*spec == ' ');
	if (c) {
	    spec++;
	}
	if ((unsigned)(d - 'A') <= (unsigned)('Z' - 'A')) {
	    d += 'a' - 'A';
	} else if (c) {
	    /* A space doesn't match a lowercase, but we don't know
	     * yet whether we should return a negative or positive
	     * number. That depends on what follows. */
	    notequal = 1;
	}
	c = *spec++;
	if ((unsigned)(c - 'A') <= (unsigned)('Z' - 'A')) {
	    c += 'a' - 'A';
	} else if (((unsigned)(c - '1') <= (unsigned)('9' - '1'))) {
	    if (d == '0') {
	    	d += 10;
	    } else if (!d) {
		num = c - '0';
		while ((unsigned)((c = *spec++) - '0') <= (unsigned)('9' - '0')) {
		    num = num * 10 + c - '0';
		}
	    }
	}
	r = c - d;
    } while(!r && d);
    if (!r && notequal) {
	/* Strings are equal, but difference in spacings only. We should still
	 * report not-equal, so "burly wood" is not a valid color */
	r = 1;
    }
    *special = num;
    return r;
}

#define RED(p) ((unsigned char)(p)[0])
#define GREEN(p) ((unsigned char)(p)[1])
#define BLUE(p) ((unsigned char)(p)[2])

Status
XParseColor(
    Display *display,
    Colormap map,
    const char *spec,
    XColor *colorPtr)
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402


403
404
405
406
407
408
409
410
411
412


413








414
415
416
417
418
419
420
421
422
423
424
	    colorPtr->green = (unsigned short) (value >> 16);
	    colorPtr->blue = (unsigned short) value;
	    break;
	default:
	    return 0;
	}
    } else {
	int size;
	const elem *p;

	/*
	 * Perform a binary search on the sorted array of colors.
	 * size = current size of search range
	 * p    = pointer to current element being considered.
	 */
	int r = (spec[0] - 'A') & 0xdf;
	if (r > (sizeof(az)/sizeof(az[0] - 1))) {
	    return 0;
	}
	size = az[r + 1] - az[r];
	p = &xColors[(az[r + 1] + az[r]) >> 1];
	r = colorcmp(spec + 1, *p);

	while (r != 0) {
	    if (r < 0) {
		size = (size >> 1);
		p -= ((size + 1) >> 1);
	    } else {
		--size;
		size = (size >> 1);
		p += ((size + 2) >> 1);
	    }
	    if (!size) {
		return 0;
	    }
	    r = colorcmp(spec + 1, *p);
	}







	colorPtr->red = ((RED(*p) << 8) | RED(*p));
	colorPtr->green = ((GREEN(*p) << 8) | GREEN(*p));
	colorPtr->blue = ((BLUE(*p) << 8) | BLUE(*p));
    }
    colorPtr->pixel = TkpGetPixel(colorPtr);
    colorPtr->flags = DoRed|DoGreen|DoBlue;
    colorPtr->pad = 0;
    return 1;
}


#if 0
int main() {
    XColor color;
    char buf[32];
    int charindex;
    int i, result;
    int repeat = 1;



    while (repeat--) {
	buf[0] = 'a';
	charindex = 1;
	for (i = 0; i < sizeof(xColors)/sizeof(xColors[0]); ++i) {
	    while (i >= az[charindex]) {
		++charindex;
		++(buf[0]);
	    }
	    strcpy(buf + 1, xColors[i]);


	    result = XParseColor(0, 0, buf, &color);








	    if (!result) {
		break;
	    }
	    printf("color %d: %s %d %d %d %d\n", i, buf, result, color.red >> 8, color.green >> 8, color.blue >> 8);
	}
    }
    if (!result) {
	printf("NOT OK: %s\n", buf);
    } else {
	printf("OK\n");
    }







|

>











|













|

>
>
>
>
>
>
>
|
|
|















>
>










>
>

>
>
>
>
>
>
>
>



<







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

448
449
450
451
452
453
454
	    colorPtr->green = (unsigned short) (value >> 16);
	    colorPtr->blue = (unsigned short) value;
	    break;
	default:
	    return 0;
	}
    } else {
	int size, num;
	const elem *p;
	const char *q;
	/*
	 * Perform a binary search on the sorted array of colors.
	 * size = current size of search range
	 * p    = pointer to current element being considered.
	 */
	int r = (spec[0] - 'A') & 0xdf;
	if (r > (sizeof(az)/sizeof(az[0] - 1))) {
	    return 0;
	}
	size = az[r + 1] - az[r];
	p = &xColors[(az[r + 1] + az[r]) >> 1];
	r = colorcmp(spec + 1, *p, &num);

	while (r != 0) {
	    if (r < 0) {
		size = (size >> 1);
		p -= ((size + 1) >> 1);
	    } else {
		--size;
		size = (size >> 1);
		p += ((size + 2) >> 1);
	    }
	    if (!size) {
		return 0;
	    }
	    r = colorcmp(spec + 1, *p, &num);
	}
	if (num > (*p)[31]) {
	    if (((*p)[31] != 8) || num > 100)
	    	return 0;
	    q = graymap + 300 - num * 3;
	} else {
	    q = *p + 28 - num * 3;
	}
	colorPtr->red = ((RED(q) << 8) | RED(q));
	colorPtr->green = ((GREEN(q) << 8) | GREEN(q));
	colorPtr->blue = ((BLUE(q) << 8) | BLUE(q));
    }
    colorPtr->pixel = TkpGetPixel(colorPtr);
    colorPtr->flags = DoRed|DoGreen|DoBlue;
    colorPtr->pad = 0;
    return 1;
}


#if 0
int main() {
    XColor color;
    char buf[32];
    int charindex;
    int i, result;
    int repeat = 1;
    int num, maxnum;
    char *end;

    while (repeat--) {
	buf[0] = 'a';
	charindex = 1;
	for (i = 0; i < sizeof(xColors)/sizeof(xColors[0]); ++i) {
	    while (i >= az[charindex]) {
		++charindex;
		++(buf[0]);
	    }
	    strcpy(buf + 1, xColors[i]);
	    end = buf + strlen(buf);
	    num = 0;
	    result = XParseColor(0, 0, buf, &color);
	    printf("%s %d %d %d\n", buf, color.red >> 8, color.green >> 8, color.blue >> 8);
	    maxnum = xColors[i][31];
	    if (maxnum == 8) maxnum = 100;
	    while (result && ++num <= maxnum) {
	    	sprintf(end, "%d", num);
		result = XParseColor(0, 0, buf, &color);
		printf("%s %d %d %d\n", buf, color.red >> 8, color.green >> 8, color.blue >> 8);
	    }
	    if (!result) {
		break;
	    }

	}
    }
    if (!result) {
	printf("NOT OK: %s\n", buf);
    } else {
	printf("OK\n");
    }