Tk Source Code

Check-in [9b2a9573]
Login

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

Overview
Comment:some upstream androwish changes
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | androwish
Files: files | file ages | folders
SHA1: 9b2a95732f82a06948ec10f49c0d4a89f45425c4
User & Date: jan.nijtmans 2017-05-18 13:19:14
Context
2017-05-19
13:30
merge rfe-6c0d7aec67 check-in: 8aa292c2 user: jan.nijtmans tags: androwish
2017-05-18
13:19
some upstream androwish changes check-in: 9b2a9573 user: jan.nijtmans tags: androwish
12:56
merge rfe-6c0d7aec67 check-in: c8bec1e6 user: jan.nijtmans tags: androwish
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to sdl/SdlTkDecframe.c.

699
700
701
702
703
704
705

706

707
708
709
710
711
712
713
		    0.0, &x, NULL);
		if (x > bb[0] - 2 * SdlTkX.dec_frame_width) {
		    break;
		}
		p += sizeof (unsigned int);
	    }


	    Tcl_FreeEncoding(encoding);

	    Tcl_DStringFree(&ds);
	}
    }

    /* Close box */
    {
#ifdef ANDROID







>
|
>







699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
		    0.0, &x, NULL);
		if (x > bb[0] - 2 * SdlTkX.dec_frame_width) {
		    break;
		}
		p += sizeof (unsigned int);
	    }

	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    Tcl_DStringFree(&ds);
	}
    }

    /* Close box */
    {
#ifdef ANDROID

Changes to sdl/SdlTkInt.c.

766
767
768
769
770
771
772
773
774



775











776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867




868
869
870
871
872
873
874
875
    return 0;
}

static int
ProcessTextInput(XEvent *event, int no_rel, int sdl_mod,
		 const char *text, int len)
{
    int i, n, n2, ulen = Tcl_NumUtfChars(text, len);
    char buf[TCL_UTF_MAX];















    if (ulen <= 0) {
	SdlTkX.keyuc = 0;
	return 0;
    }
    if (sdl_mod & KMOD_RALT) {
	event->xkey.state &= ~Mod4Mask;
    }
    for (i = 0; i < ulen; i++) {
	Tcl_UniChar ch;

	n = Tcl_UtfToUniChar(text, &ch);
	n2 = 0;

	/* Deal with surrogate pairs */
#if TCL_UTF_MAX > 4
	if ((ch >= 0xd800) && (ch <= 0xdbff)) {
	    Tcl_UniChar ch2;

	    if (i + 1 < ulen) {
		n2 = Tcl_UtfToUniChar(text + n, &ch2);
		if ((ch2 >= 0xdc00) && (ch2 <= 0xdfff)) {
		    ch = ((ch & 0x3ff) << 10) | (ch2 & 0x3ff);
		    ch += 0x10000;
		    ++i;
		} else {
		    ch = 0xfffd;
		    n2 = 0;
		}
	    } else {
		SdlTkX.keyuc = ch;
		return -1;
	    }
	} else if ((ch >= 0xdc00) && (ch <= 0xdfff)) {
	    if (SdlTkX.keyuc) {
		ch = ((SdlTkX.keyuc & 0x3ff) << 10) | (ch & 0x3ff);
		ch += 0x10000;
	    } else {
		ch = 0xfffd;
	    }
	    SdlTkX.keyuc = 0;
	} else if ((ch == 0xfffe) || (ch == 0xffff)) {
	    ch = 0xfffd;
	    SdlTkX.keyuc = 0;
	} else {
	    SdlTkX.keyuc = 0;
	}
#else
	if ((ch >= 0xd800) && (ch <= 0xdbff)) {
	    Tcl_UniChar ch2;

	    if (i + 1 < ulen) {
		n2 = Tcl_UtfToUniChar(text + n, &ch2);
		if ((ch2 >= 0xdc00) && (ch2 <= 0xdfff)) {
		    ++i;
		} else {
		    n2 = 0;
		}
	    }
	    ch = 0xfffd;
	} else if ((ch >= 0xdc00) && (ch <= 0xdfff)) {
	    ch = 0xfffd;
	} else if ((ch == 0xfffe) || (ch == 0xffff)) {
	    ch = 0xfffd;
	}
	SdlTkX.keyuc = 0;
#endif
	event->xkey.nbytes = Tcl_UniCharToUtf(ch, buf);
	event->xkey.time = SdlTkX.time_count;
	if (event->xkey.nbytes > sizeof (event->xkey.trans_chars)) {
	    event->xkey.nbytes = sizeof (event->xkey.trans_chars);
	}
	memcpy(event->xkey.trans_chars, buf, event->xkey.nbytes);
	if (len == 1) {
	    event->xkey.keycode = FixKeyCode(event->xkey.trans_chars[0]);
	} else {
	    event->xkey.keycode = -1;
	}
	text += n + n2;

	/* Queue the KeyPress */
	EVLOG("   KEYPRESS:  CODE=0x%02X  UC=0x%X", event->xkey.keycode, ch);
	event->type = KeyPress;
	if (!no_rel || (i < ulen - 1)) {
	    SdlTkQueueEvent(event);
	    /* Queue the KeyRelease except for the last */
	    event->type = KeyRelease;
	    if (i < ulen - 1) {
		EVLOG(" KEYRELEASE:  CODE=0x%02X", event->xkey.keycode);
		SdlTkQueueEvent(event);
	    }
	}
    }




    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * SdlTkTranslateEvent --
 *







|

>
>
>

>
>
>
>
>
>
>
>
>
>
>

|
|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











|














>
>
>
>
|







766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800























































801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
    return 0;
}

static int
ProcessTextInput(XEvent *event, int no_rel, int sdl_mod,
		 const char *text, int len)
{
    int ret, i, n, ulen;
    char buf[TCL_UTF_MAX];
#if TCL_UTF_MAX < 4
    Tcl_DString ubuf;
    Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "utf-8");

    /*
     * This should make UTF-8 into WTF-8.
     */
    Tcl_DStringInit(&ubuf);
    Tcl_ExternalToUtfDString(encoding, text, len, &ubuf);
    if (encoding) {
	Tcl_FreeEncoding(encoding);
    }
    text = Tcl_DStringValue(&ubuf);
#endif
    ulen = Tcl_NumUtfChars(text, len);
    if (ulen <= 0) {
	ret = 0;
	goto done;
    }
    if (sdl_mod & KMOD_RALT) {
	event->xkey.state &= ~Mod4Mask;
    }
    for (i = 0; i < ulen; i++) {
	Tcl_UniChar ch;

	n = Tcl_UtfToUniChar(text, &ch);























































	event->xkey.nbytes = Tcl_UniCharToUtf(ch, buf);
	event->xkey.time = SdlTkX.time_count;
	if (event->xkey.nbytes > sizeof (event->xkey.trans_chars)) {
	    event->xkey.nbytes = sizeof (event->xkey.trans_chars);
	}
	memcpy(event->xkey.trans_chars, buf, event->xkey.nbytes);
	if (len == 1) {
	    event->xkey.keycode = FixKeyCode(event->xkey.trans_chars[0]);
	} else {
	    event->xkey.keycode = -1;
	}
	text += n;

	/* Queue the KeyPress */
	EVLOG("   KEYPRESS:  CODE=0x%02X  UC=0x%X", event->xkey.keycode, ch);
	event->type = KeyPress;
	if (!no_rel || (i < ulen - 1)) {
	    SdlTkQueueEvent(event);
	    /* Queue the KeyRelease except for the last */
	    event->type = KeyRelease;
	    if (i < ulen - 1) {
		EVLOG(" KEYRELEASE:  CODE=0x%02X", event->xkey.keycode);
		SdlTkQueueEvent(event);
	    }
	}
    }
done:
#if TCL_UTF_MAX < 4
    Tcl_DStringFree(&ubuf);
#endif
    return ret;
}

/*
 *----------------------------------------------------------------------
 *
 * SdlTkTranslateEvent --
 *

Changes to sdl/SdlTkInt.h.

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
    int nearby_pixels;
    TkWindow *capture_window;
    _Window *mouse_window;
    _Window *keyboard_window;
    int mouse_x;
    int mouse_y;
    int sdlfocus;
    int keyuc;
    int cursor_change;
#ifndef ANDROID
    Tcl_HashTable sdlcursors;
#endif

    /* Screen refresh, life-cycle */
    Region screen_dirty_region;







<







200
201
202
203
204
205
206

207
208
209
210
211
212
213
    int nearby_pixels;
    TkWindow *capture_window;
    _Window *mouse_window;
    _Window *keyboard_window;
    int mouse_x;
    int mouse_y;
    int sdlfocus;

    int cursor_change;
#ifndef ANDROID
    Tcl_HashTable sdlcursors;
#endif

    /* Screen refresh, life-cycle */
    Region screen_dirty_region;

Changes to sdl/SdlTkUtils.c.

641
642
643
644
645
646
647

648
649
650
651
652
653
654













655
656
657
658
659
660
661
    wSrcStart = (unsigned int *) src;
    wSrcEnd = (unsigned int *) (src + srcLen);

    dstStart = dst;
    dstEnd = dst + dstLen - TCL_UTF_MAX;

    for (numChars = 0; wSrc < wSrcEnd; numChars++) {

        Tcl_UniChar ch;

	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	ch = *wSrc++;













	dst += Tcl_UniCharToUtf(ch, dst);
    }

    *srcReadPtr = (char *) wSrc - (char *) wSrcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;







>






|
>
>
>
>
>
>
>
>
>
>
>
>
>







641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
    wSrcStart = (unsigned int *) src;
    wSrcEnd = (unsigned int *) (src + srcLen);

    dstStart = dst;
    dstEnd = dst + dstLen - TCL_UTF_MAX;

    for (numChars = 0; wSrc < wSrcEnd; numChars++) {
	int uch;
        Tcl_UniChar ch;

	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	uch = *wSrc++;
	ch = uch;
#if TCL_UTF_MAX < 4
	if (uch > 0xFFFF && uch < 0x10FFFF) {
	    uch -= 0x10000;
	    ch = (uch & 0x3FF) | 0xDC00;
	    dst += Tcl_UniCharToUtf((Tcl_UniChar)((uch >> 10) | 0xD800), dst);
	    if (dst >= dstEnd) {
		result = TCL_CONVERT_NOSPACE;
		break;
	    }
	    numChars++;
	}
#endif
	dst += Tcl_UniCharToUtf(ch, dst);
    }

    *srcReadPtr = (char *) wSrc - (char *) wSrcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740










741
742
743
744
745
746
747
748
749
750
751
752
753
754
755

    wDst = (unsigned int *) dst;
    wDstStart = (unsigned int *) dst;
    wDstEnd = (unsigned int *) (dst + dstLen - sizeof (unsigned int));

    result = TCL_OK;
    for (numChars = 0; src < srcEnd; numChars++) {

	Tcl_UniChar ucs2;

	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
	if (wDst > wDstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
        }
	src += Tcl_UtfToUniChar(src, &ucs2);










#ifdef USE_SYMBOLA_CTRL
	if ((ucs2 >= 0x00) && (ucs2 < 0x20)) {
	    ucs2 += 0x2400;
	} else if (ucs2 == 0x7F) {
	    ucs2 = 0x2421;
	}
#endif
	*wDst++ = ucs2;
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = (char *) wDst - (char *) wDstStart;
    *dstCharsPtr = numChars;
    return result;
}








>
|














|
>
>
>
>
>
>
>
>
>
>

|
|
|
|


|







732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

    wDst = (unsigned int *) dst;
    wDstStart = (unsigned int *) dst;
    wDstEnd = (unsigned int *) (dst + dstLen - sizeof (unsigned int));

    result = TCL_OK;
    for (numChars = 0; src < srcEnd; numChars++) {
	int ch, len;
	Tcl_UniChar ucs, ucs2;

	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
	if (wDst > wDstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
        }
	src += Tcl_UtfToUniChar(src, &ucs);
	ch = ucs;
	if ((ucs & 0xFFFFFC00) == 0xD800) {
	    if (Tcl_UtfCharComplete(src, srcEnd - src)) {
		len = Tcl_UtfToUniChar(src, &ucs2);
		if ((ucs2 & 0xFFFFFC00) == 0xDC00) {
		    src += len;
		    ch = (((ucs&0x3FF)<<10) | (ucs2&0x3FF)) + 0x10000;
		}
	    }
	}
#ifdef USE_SYMBOLA_CTRL
	if ((ch >= 0x00) && (ch < 0x20)) {
	    ch += 0x2400;
	} else if (ch == 0x7F) {
	    ch = 0x2421;
	}
#endif
	*wDst++ = ch;
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = (char *) wDst - (char *) wDstStart;
    *dstCharsPtr = numChars;
    return result;
}

Changes to sdl/tkSDLFont.c.

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 * character existence metrics, used to determine if a screen font can display
 * a given Unicode character.
 *
 * Under Unix, there are three attributes that uniquely identify a "font
 * family": the foundry, face name, and charset.
 */

#if TCL_UTF_MAX > 3
#define FONTMAP_SHIFT		12
#define FONTMAP_PAGES		(1 << (21 - FONTMAP_SHIFT))
#else
#define FONTMAP_SHIFT		10
#define FONTMAP_PAGES		(1 << (sizeof(Tcl_UniChar)*8 - FONTMAP_SHIFT))
#endif
#define FONTMAP_BITSPERPAGE	(1 << FONTMAP_SHIFT)

typedef struct FontFamily {
    struct FontFamily *nextPtr;	/* Next in list of all known font families. */
    int refCount;		/* How many SubFonts are referring to this
				 * FontFamily. When the refCount drops to
				 * zero, this FontFamily may be freed. */







<


<
<
<
<







29
30
31
32
33
34
35

36
37




38
39
40
41
42
43
44
 * character existence metrics, used to determine if a screen font can display
 * a given Unicode character.
 *
 * Under Unix, there are three attributes that uniquely identify a "font
 * family": the foundry, face name, and charset.
 */


#define FONTMAP_SHIFT		12
#define FONTMAP_PAGES		(1 << (21 - FONTMAP_SHIFT))




#define FONTMAP_BITSPERPAGE	(1 << FONTMAP_SHIFT)

typedef struct FontFamily {
    struct FontFamily *nextPtr;	/* Next in list of all known font families. */
    int refCount;		/* How many SubFonts are referring to this
				 * FontFamily. When the refCount drops to
				 * zero, this FontFamily may be freed. */
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
} SubFont;

/*
 * The following structure represents Unix's implementation of a font object.
 */

#define SUBFONT_SPACE		3
#if TCL_UTF_MAX > 3
#define BASE_CHARS		4096
#else
#define BASE_CHARS		2048
#endif

typedef struct UnixFont {
    TkFont font;		/* Stuff used by generic font package. Must be
				 * first in structure. */
    SubFont staticSubFonts[SUBFONT_SPACE];
				/* Builtin space for a limited number of
				 * SubFonts. */







<

<
<
<







83
84
85
86
87
88
89

90



91
92
93
94
95
96
97
} SubFont;

/*
 * The following structure represents Unix's implementation of a font object.
 */

#define SUBFONT_SPACE		3

#define BASE_CHARS		4096




typedef struct UnixFont {
    TkFont font;		/* Stuff used by generic font package. Must be
				 * first in structure. */
    SubFont staticSubFonts[SUBFONT_SPACE];
				/* Builtin space for a limited number of
				 * SubFonts. */
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
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    char *dstStart, *dstEnd;
    unsigned int *wDst;
    Tcl_UniChar ch;
    int result;
    static char hexChars[] = "0123456789abcdef";
    static char mapChars[] = {
	0, 0, 0, 0, 0, 0, 0,
	'a', 'b', 't', 'n', 'v', 'f', 'r'
    };

    result = TCL_OK;

    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
#if TCL_UTF_MAX > 3
    dstEnd = dst + dstLen - 10 * sizeof(unsigned int);
#else
    dstEnd = dst + dstLen - 6 * sizeof(unsigned int);
#endif
    wDst = (unsigned int *) dst;

    for ( ; src < srcEnd; ) {
	if ((char *) wDst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	src += Tcl_UtfToUniChar(src, &ch);
	wDst[0] = '\\';
	if ((ch < sizeof(mapChars)) && (mapChars[ch] != 0)) {
	    wDst[1] = mapChars[ch];
	    wDst += 2;
	} else if (ch < 256) {
	    wDst[1] = 'x';
	    wDst[2] = hexChars[(ch >> 4) & 0xf];
	    wDst[3] = hexChars[ch & 0xf];
	    wDst += 4;
#if TCL_UTF_MAX > 3
	} else if (ch < 0x10000)  {
	    wDst[1] = 'u';
	    wDst[2] = hexChars[(ch >> 12) & 0xf];
	    wDst[3] = hexChars[(ch >> 8) & 0xf];
	    wDst[4] = hexChars[(ch >> 4) & 0xf];
	    wDst[5] = hexChars[ch & 0xf];
	    wDst += 6;







<
|












<

<
<
<







|









<







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
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    char *dstStart, *dstEnd;
    unsigned int *wDst;

    int ch, result;
    static char hexChars[] = "0123456789abcdef";
    static char mapChars[] = {
	0, 0, 0, 0, 0, 0, 0,
	'a', 'b', 't', 'n', 'v', 'f', 'r'
    };

    result = TCL_OK;

    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;

    dstEnd = dst + dstLen - 10 * sizeof(unsigned int);



    wDst = (unsigned int *) dst;

    for ( ; src < srcEnd; ) {
	if ((char *) wDst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	src += TkUtfToUniChar(src, &ch);
	wDst[0] = '\\';
	if ((ch < sizeof(mapChars)) && (mapChars[ch] != 0)) {
	    wDst[1] = mapChars[ch];
	    wDst += 2;
	} else if (ch < 256) {
	    wDst[1] = 'x';
	    wDst[2] = hexChars[(ch >> 4) & 0xf];
	    wDst[3] = hexChars[ch & 0xf];
	    wDst += 4;

	} else if (ch < 0x10000)  {
	    wDst[1] = 'u';
	    wDst[2] = hexChars[(ch >> 12) & 0xf];
	    wDst[3] = hexChars[(ch >> 8) & 0xf];
	    wDst[4] = hexChars[(ch >> 4) & 0xf];
	    wDst[5] = hexChars[ch & 0xf];
	    wDst += 6;
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
	    wDst[4] = hexChars[(ch >> 20) & 0xf];
	    wDst[5] = hexChars[(ch >> 16) & 0xf];
	    wDst[6] = hexChars[(ch >> 12) & 0xf];
	    wDst[7] = hexChars[(ch >> 8) & 0xf];
	    wDst[8] = hexChars[(ch >> 4) & 0xf];
	    wDst[9] = hexChars[ch & 0xf];
	    wDst += 10;
#else
	} else {
	    wDst[1] = 'u';
	    wDst[2] = hexChars[(ch >> 12) & 0xf];
	    wDst[3] = hexChars[(ch >> 8) & 0xf];
	    wDst[4] = hexChars[(ch >> 4) & 0xf];
	    wDst[5] = hexChars[ch & 0xf];
	    wDst += 6;
#endif
	}
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = (char *) wDst - dstStart;
    *dstCharsPtr = *dstWrotePtr / sizeof(unsigned int);
    return result;
}







<
<
<
<
<
<
<
<
<







415
416
417
418
419
420
421









422
423
424
425
426
427
428
	    wDst[4] = hexChars[(ch >> 20) & 0xf];
	    wDst[5] = hexChars[(ch >> 16) & 0xf];
	    wDst[6] = hexChars[(ch >> 12) & 0xf];
	    wDst[7] = hexChars[(ch >> 8) & 0xf];
	    wDst[8] = hexChars[(ch >> 4) & 0xf];
	    wDst[9] = hexChars[ch & 0xf];
	    wDst += 10;









	}
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = (char *) wDst - dstStart;
    *dstCharsPtr = *dstWrotePtr / sizeof(unsigned int);
    return result;
}
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
    lastSubFontPtr = &fontPtr->subFontArray[0];

    if (numBytes == 0) {
	curX = 0;
	curByte = 0;
    } else if (maxLength < 0) {
	const char *p, *end, *next;
	Tcl_UniChar ch;
	SubFont *thisSubFontPtr;
	FontFamily *familyPtr;
	Tcl_DString runString;

	/*
	 * A three step process:
	 * 1. Find a contiguous range of characters that can all be
	 *    represented by a single screen font.
	 * 2. Convert those chars to the encoding of that font.
	 * 3. Measure converted chars.
	 */

	curX = 0;
	end = source + numBytes;
	for (p = source; p < end; ) {
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	    if (thisSubFontPtr != lastSubFontPtr) {
		familyPtr = lastSubFontPtr->familyPtr;
		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			p - source, &runString);
		if (lastSubFontPtr == &fontPtr->controlSubFont) {
		    fontSize =







|















|







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
    lastSubFontPtr = &fontPtr->subFontArray[0];

    if (numBytes == 0) {
	curX = 0;
	curByte = 0;
    } else if (maxLength < 0) {
	const char *p, *end, *next;
	int ch;
	SubFont *thisSubFontPtr;
	FontFamily *familyPtr;
	Tcl_DString runString;

	/*
	 * A three step process:
	 * 1. Find a contiguous range of characters that can all be
	 *    represented by a single screen font.
	 * 2. Convert those chars to the encoding of that font.
	 * 3. Measure converted chars.
	 */

	curX = 0;
	end = source + numBytes;
	for (p = source; p < end; ) {
	    next = p + TkUtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	    if (thisSubFontPtr != lastSubFontPtr) {
		familyPtr = lastSubFontPtr->familyPtr;
		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			p - source, &runString);
		if (lastSubFontPtr == &fontPtr->controlSubFont) {
		    fontSize =
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
	if (lastSubFontPtr == &fontPtr->controlSubFont) {
	    SdlTkFontRestore(lastSubFontPtr->fontStructPtr, fontSize);
	}
	Tcl_DStringFree(&runString);
	curByte = numBytes;
    } else {
	const char *p, *end, *next, *term;
	int newX, termX, sawNonSpace, dstWrote;
	Tcl_UniChar ch;
	FontFamily *familyPtr;
	char buf[64];

	/*
	 * How many chars will fit in the space allotted? This first version
	 * may be inefficient because it measures every character
	 * individually.
	 */

	next = source + Tcl_UtfToUniChar(source, &ch);
	newX = curX = termX = 0;

	term = source;
	end = source + numBytes;

	sawNonSpace = (ch > 255) || !isspace(ch);
	familyPtr = lastSubFontPtr->familyPtr;







|
<









|







912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
	if (lastSubFontPtr == &fontPtr->controlSubFont) {
	    SdlTkFontRestore(lastSubFontPtr->fontStructPtr, fontSize);
	}
	Tcl_DStringFree(&runString);
	curByte = numBytes;
    } else {
	const char *p, *end, *next, *term;
	int newX, termX, sawNonSpace, dstWrote, ch;

	FontFamily *familyPtr;
	char buf[64];

	/*
	 * How many chars will fit in the space allotted? This first version
	 * may be inefficient because it measures every character
	 * individually.
	 */

	next = source + TkUtfToUniChar(source, &ch);
	newX = curX = termX = 0;

	term = source;
	end = source + numBytes;

	sawNonSpace = (ch > 255) || !isspace(ch);
	familyPtr = lastSubFontPtr->familyPtr;
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
	    p = next;
	    if (p >= end) {
		term = end;
		termX = curX;
		break;
	    }

	    next += Tcl_UtfToUniChar(next, &ch);
	    if ((ch < 256) && isspace(ch)) {
		if (sawNonSpace) {
		    term = p;
		    termX = curX;
		    sawNonSpace = 0;
		}
	    } else {







|







968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
	    p = next;
	    if (p >= end) {
		term = end;
		termX = curX;
		break;
	    }

	    next += TkUtfToUniChar(next, &ch);
	    if ((ch < 256) && isspace(ch)) {
		if (sawNonSpace) {
		    term = p;
		    termX = curX;
		    sawNonSpace = 0;
		}
	    } else {
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
	    /*
	     * Include the first character that didn't quite fit in the
	     * desired span. The width returned will include the width of that
	     * extra character.
	     */

	    curX = newX;
	    p += Tcl_UtfToUniChar(p, &ch);
	}
	if ((flags & TK_AT_LEAST_ONE) && (term == source) && (p < end)) {
	    term = p;
	    termX = curX;
	    if (term == source) {
		term += Tcl_UtfToUniChar(term, &ch);
		termX = newX;
	    }
	} else if ((p >= end) || !(flags & TK_WHOLE_WORDS)) {
	    term = p;
	    termX = curX;
	}








|





|







993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
	    /*
	     * Include the first character that didn't quite fit in the
	     * desired span. The width returned will include the width of that
	     * extra character.
	     */

	    curX = newX;
	    p += TkUtfToUniChar(p, &ch);
	}
	if ((flags & TK_AT_LEAST_ONE) && (term == source) && (p < end)) {
	    term = p;
	    termX = curX;
	    if (term == source) {
		term += TkUtfToUniChar(term, &ch);
		termX = newX;
	    }
	} else if ((p >= end) || !(flags & TK_WHOLE_WORDS)) {
	    term = p;
	    termX = curX;
	}

1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    UnixFont *fontPtr = (UnixFont *) tkfont;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    Tcl_DString runString;
    const char *p, *end, *next;
    int xStart, window_width;
    Tcl_UniChar ch;
    FontFamily *familyPtr;
    int rx, ry, fontSize = 0;
    unsigned width, height, border_width, depth;
    Drawable root;

    lastSubFontPtr = &fontPtr->subFontArray[0];
    xStart = x;







|
<







1111
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    UnixFont *fontPtr = (UnixFont *) tkfont;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    Tcl_DString runString;
    const char *p, *end, *next;
    int xStart, window_width, ch;

    FontFamily *familyPtr;
    int rx, ry, fontSize = 0;
    unsigned width, height, border_width, depth;
    Drawable root;

    lastSubFontPtr = &fontPtr->subFontArray[0];
    xStart = x;
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
    } else {
	window_width = width;
    }

    end = source + numBytes;
    for (p = source; p <= end; ) {
	if (p < end) {
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	} else {
	    next = p + 1;
	    thisSubFontPtr = lastSubFontPtr;
	}
	if ((thisSubFontPtr != lastSubFontPtr)
		|| (p == end) || (p-source > 200)) {







|







1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
    } else {
	window_width = width;
    }

    end = source + numBytes;
    for (p = source; p <= end; ) {
	if (p < end) {
	    next = p + TkUtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	} else {
	    next = p + 1;
	    thisSubFontPtr = lastSubFontPtr;
	}
	if ((thisSubFontPtr != lastSubFontPtr)
		|| (p == end) || (p-source > 200)) {
1697
1698
1699
1700
1701
1702
1703

1704

1705
1706
1707
1708
1709
1710
1711
    encoding = Tcl_GetEncoding(NULL, GetEncodingAlias(fa.xa.charset));

    familyPtr = tsdPtr->fontFamilyList;
    for (; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
	if ((familyPtr->faceName == fa.fa.family)
		&& (familyPtr->foundry == fa.xa.foundry)
		&& (familyPtr->encoding == encoding)) {

	    Tcl_FreeEncoding(encoding);

	    familyPtr->refCount++;
	    return familyPtr;
	}
    }

    familyPtr = ckalloc(sizeof(FontFamily));
    memset(familyPtr, 0, sizeof(FontFamily));







>
|
>







1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
    encoding = Tcl_GetEncoding(NULL, GetEncodingAlias(fa.xa.charset));

    familyPtr = tsdPtr->fontFamilyList;
    for (; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
	if ((familyPtr->faceName == fa.fa.family)
		&& (familyPtr->foundry == fa.xa.foundry)
		&& (familyPtr->encoding == encoding)) {
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    familyPtr->refCount++;
	    return familyPtr;
	}
    }

    familyPtr = ckalloc(sizeof(FontFamily));
    memset(familyPtr, 0, sizeof(FontFamily));
1767
1768
1769
1770
1771
1772
1773

1774

1775
1776
1777
1778
1779
1780
1781
    if (familyPtr == NULL) {
	return;
    }
    familyPtr->refCount--;
    if (familyPtr->refCount > 0) {
	return;
    }

    Tcl_FreeEncoding(familyPtr->encoding);

    for (i = 0; i < FONTMAP_PAGES; i++) {
	if (familyPtr->fontMap[i] != NULL) {
	    ckfree(familyPtr->fontMap[i]);
	}
    }

    /*







>
|
>







1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
    if (familyPtr == NULL) {
	return;
    }
    familyPtr->refCount--;
    if (familyPtr->refCount > 0) {
	return;
    }
    if (familyPtr->encoding) {
	Tcl_FreeEncoding(familyPtr->encoding);
    }
    for (i = 0; i < FONTMAP_PAGES; i++) {
	if (familyPtr->fontMap[i] != NULL) {
	    ckfree(familyPtr->fontMap[i]);
	}
    }

    /*
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
    }

    end = (row + 1) << FONTMAP_SHIFT;
    for (i = row << FONTMAP_SHIFT; i < end; i++) {
	if ((i >= 0xD800) && (i <= 0xDFFF)) {
	    continue;
	}
	if (Tcl_UtfToExternal(NULL, encoding, src, Tcl_UniCharToUtf(i, src),
		TCL_ENCODING_STOPONERROR, NULL, buf, sizeof(buf), NULL,
		NULL, NULL) != TCL_OK) {
	    continue;
	}
	if (SdlTkFontHasChar(subFontPtr->fontStructPtr, buf)) {
	    bitOffset = i & (FONTMAP_BITSPERPAGE - 1);
	    subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);







|







2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
    }

    end = (row + 1) << FONTMAP_SHIFT;
    for (i = row << FONTMAP_SHIFT; i < end; i++) {
	if ((i >= 0xD800) && (i <= 0xDFFF)) {
	    continue;
	}
	if (Tcl_UtfToExternal(NULL, encoding, src, TkUniCharToUtf(i, src),
		TCL_ENCODING_STOPONERROR, NULL, buf, sizeof(buf), NULL,
		NULL, NULL) != TCL_OK) {
	    continue;
	}
	if (SdlTkFontHasChar(subFontPtr->fontStructPtr, buf)) {
	    bitOffset = i & (FONTMAP_BITSPERPAGE - 1);
	    subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
 *---------------------------------------------------------------------------
 */

static SubFont *
CanUseFallbackWithAliases(
    UnixFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    const char *faceName,		/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    Tcl_DString *nameTriedPtr,	/* Records face names that have already been
				 * tried. It is possible for the same face
				 * name to be queried multiple times when
				 * trying to find a suitable screen font. */
    SubFont **fixSubFontPtrPtr)	/* Subfont reference to fix up if we







|







2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
 *---------------------------------------------------------------------------
 */

static SubFont *
CanUseFallbackWithAliases(
    UnixFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    const char *faceName,	/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    Tcl_DString *nameTriedPtr,	/* Records face names that have already been
				 * tried. It is possible for the same face
				 * name to be queried multiple times when
				 * trying to find a suitable screen font. */
    SubFont **fixSubFontPtrPtr)	/* Subfont reference to fix up if we
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
    if (angle == 0.0) {
	Tk_DrawChars(display, drawable, gc, tkfont, source, numBytes, x, y);
    } else {
	UnixFont *fontPtr = (UnixFont *) tkfont;
	SubFont *thisSubFontPtr, *lastSubFontPtr;
	Tcl_DString runString;
	const char *p, *end, *next;
	int xStart, yStart, fontSize = 0;
	Tcl_UniChar ch;
	FontFamily *familyPtr;
        double sinA = sin(angle*PI/180), cosA = cos(angle*PI/180), dy;
        XPoint points[5];

	lastSubFontPtr = &fontPtr->subFontArray[0];
	xStart = x;
	yStart = y;

	end = source + numBytes;
	for (p = source; p <= end; ) {
	    if (p < end) {
		next = p + Tcl_UtfToUniChar(p, &ch);
		thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	    } else {
		next = p + 1;
		thisSubFontPtr = lastSubFontPtr;
	    }
	    if ((thisSubFontPtr != lastSubFontPtr)
		    || (p == end) || (p-source > 200)) {







|
<











|







2822
2823
2824
2825
2826
2827
2828
2829

2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
    if (angle == 0.0) {
	Tk_DrawChars(display, drawable, gc, tkfont, source, numBytes, x, y);
    } else {
	UnixFont *fontPtr = (UnixFont *) tkfont;
	SubFont *thisSubFontPtr, *lastSubFontPtr;
	Tcl_DString runString;
	const char *p, *end, *next;
	int xStart, yStart, fontSize = 0, ch;

	FontFamily *familyPtr;
        double sinA = sin(angle*PI/180), cosA = cos(angle*PI/180), dy;
        XPoint points[5];

	lastSubFontPtr = &fontPtr->subFontArray[0];
	xStart = x;
	yStart = y;

	end = source + numBytes;
	for (p = source; p <= end; ) {
	    if (p < end) {
		next = p + TkUtfToUniChar(p, &ch);
		thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	    } else {
		next = p + 1;
		thisSubFontPtr = lastSubFontPtr;
	    }
	    if ((thisSubFontPtr != lastSubFontPtr)
		    || (p == end) || (p-source > 200)) {

Changes to sdl/tkSDLMenu.c.

862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
	Tcl_GetUnicodeFromObj(mePtr->labelPtr, &len);
	if (mePtr->underline < len) {
	    int activeBorderWidth, leftEdge;
	    const char *label, *start, *end;

	    label = Tcl_GetString(mePtr->labelPtr);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    end = Tcl_UtfNext(start);

	    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		    menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	    leftEdge = x + mePtr->indicatorSpace + activeBorderWidth;
	    if (menuPtr->menuType == MENUBAR) {
		leftEdge += 5;
	    }







|







862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
	Tcl_GetUnicodeFromObj(mePtr->labelPtr, &len);
	if (mePtr->underline < len) {
	    int activeBorderWidth, leftEdge;
	    const char *label, *start, *end;

	    label = Tcl_GetString(mePtr->labelPtr);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    end = TkUtfNext(start);

	    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		    menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	    leftEdge = x + mePtr->indicatorSpace + activeBorderWidth;
	    if (menuPtr->menuType == MENUBAR) {
		leftEdge += 5;
	    }