Tk Source Code

Check-in [1516a46a]
Login

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

Overview
Comment:Reasonable fix for [1096580fff] - soft-hyphen in text widget
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | bug-1096580fff | soft-hyphen
Files: files | file ages | folders
SHA1: 1516a46a81e4cff0a6ddc057cc71c7cdeac7e205
User & Date: fvogel 2016-10-16 20:29:42
References
2016-10-16
20:57 Ticket [1096580f] soft-hyphen in text widget status still Open with 3 other changes artifact: 8af3d8b1 user: fvogel
Context
2016-11-01
21:31
(Hopefully) fixed compilation issue on OSX as reported by Brad Lanam in [1096580fff], by properly calling the adequate Tcl routines for manipulation of UTF-8 strings check-in: ea75c23f user: fvogel tags: bug-1096580fff, soft-hyphen
2016-10-16
20:29
Reasonable fix for [1096580fff] - soft-hyphen in text widget check-in: 1516a46a user: fvogel tags: bug-1096580fff, soft-hyphen
19:44
Added test textDisp-2.36 counting chars and displaychars in presence of soft hyphens. check-in: 5691e299 user: fvogel tags: bug-1096580fff, soft-hyphen
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkTextDisp.c.

1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484










1485
1486
1487
1488
1489

1490
1491
1492

1493
1494
1495
1496
1497
1498
1499
	    }
	}

	gotTab = 0;
	maxBytes = segPtr->size - byteOffset;
	if (segPtr->typePtr == &tkTextCharType) {

	    /*
	     * See if there is a tab in the current segment; if so, only layout
	     * characters up to (and including) the tab.
	     */











	    if (!elide && justify == TK_JUSTIFY_LEFT) {
		char *p;

		for (p = segPtr->body.chars + byteOffset; *p != 0; p++) {
		    if (*p == '\t') {

			maxBytes = (p + 1 - segPtr->body.chars) - byteOffset;
			gotTab = 1;
			break;

		    }
		}
	    }

#if TK_LAYOUT_WITH_BASE_CHUNKS
	    if (baseCharChunkPtr != NULL) {
		int expectedX =







|
|
|
|

>
>
>
>
>
>
>
>
>
>





>
|
|
|
>







1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
	    }
	}

	gotTab = 0;
	maxBytes = segPtr->size - byteOffset;
	if (segPtr->typePtr == &tkTextCharType) {

            /*
             * See if there is a tab or soft hyphen in the current segment; if so,
             * only layout characters up to (and including) this character.
             */

            if (!elide) {
                char *p;

                for (p = segPtr->body.chars + byteOffset; *p != 0; p++) {
                    if (*p == '\u00AD') {
                        maxBytes = (p + 1 - segPtr->body.chars) - byteOffset;
                        break;
                    }
                }
            }
	    if (!elide && justify == TK_JUSTIFY_LEFT) {
		char *p;

		for (p = segPtr->body.chars + byteOffset; *p != 0; p++) {
		    if (*p == '\t') {
                        if ((p + 1 - segPtr->body.chars) - byteOffset <= maxBytes) {
                            maxBytes = (p + 1 - segPtr->body.chars) - byteOffset;
			    gotTab = 1;
			    break;
                        }
		    }
		}
	    }

#if TK_LAYOUT_WITH_BASE_CHUNKS
	    if (baseCharChunkPtr != NULL) {
		int expectedX =
7679
7680
7681
7682
7683
7684
7685
7686
7687

7688
7689
7690


7691
7692
7693
7694
7695
7696
7697
     * Final update for the current base chunk data.
     */

    Tcl_DStringSetLength(baseString,lineOffset+ciPtr->numBytes);
    bciPtr->width = nextX - baseCharChunkPtr->x;

    /*
     * Finalize the base chunk if this chunk ends in a tab, which definitly
     * breaks the context and needs to be handled on a higher level.

     */

    if (ciPtr->numBytes > 0 && p[ciPtr->numBytes - 1] == '\t') {


	FinalizeBaseChunk(chunkPtr);
    }
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */

    /*
     * Compute a break location. If we're in word wrap mode, a break can occur
     * after any space character, or at the end of the chunk if the next







|
|
>



>
>







7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
     * Final update for the current base chunk data.
     */

    Tcl_DStringSetLength(baseString,lineOffset+ciPtr->numBytes);
    bciPtr->width = nextX - baseCharChunkPtr->x;

    /*
     * Finalize the base chunk if this chunk ends in a tab or soft hyphen,
     * which definitely breaks the context and needs to be handled on a
     * higher level.
     */

    if (ciPtr->numBytes > 0 && p[ciPtr->numBytes - 1] == '\t') {
	FinalizeBaseChunk(chunkPtr);
    } else if (ciPtr->numBytes > 1 && p[ciPtr->numBytes - 1] == '\u00AD') {
	FinalizeBaseChunk(chunkPtr);
    }
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */

    /*
     * Compute a break location. If we're in word wrap mode, a break can occur
     * after any space character, or at the end of the chunk if the next
7934
7935
7936
7937
7938
7939
7940













7941
7942
7943
7944
7945
7946
7947
	int start = ciPtr->baseOffset + offsetBytes;
	int len = ciPtr->numBytes - offsetBytes;
	int xDisplacement = x - chunkPtr->x;

	if ((len > 0) && (string[start + len - 1] == '\t')) {
	    len--;
	}













	if (len <= 0) {
	    return;
	}

	TkpDrawCharsInContext(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
		string, numBytes, start, len,
		ciPtr->baseChunkPtr->x + xDisplacement,







>
>
>
>
>
>
>
>
>
>
>
>
>







7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
	int start = ciPtr->baseOffset + offsetBytes;
	int len = ciPtr->numBytes - offsetBytes;
	int xDisplacement = x - chunkPtr->x;

	if ((len > 0) && (string[start + len - 1] == '\t')) {
	    len--;
	}

        /*
         * Don't draw any soft hyphen unless it is the last character
         * of the display line. Soft hyphens can only show up at the
         * end of a chunk, so test their presence at this place only.
         */

        if (chunkPtr->nextPtr != NULL) {
            if ((len > 1) && (string[start + len - 1] == '\u00AD')) {
                len = len - 2;
            }
        }

	if (len <= 0) {
	    return;
	}

	TkpDrawCharsInContext(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
		string, numBytes, start, len,
		ciPtr->baseChunkPtr->x + xDisplacement,
7968
7969
7970
7971
7972
7973
7974













7975
7976
7977
7978
7979
7980
7981
#else /* !TK_DRAW_IN_CONTEXT */
	string += offsetBytes;
	numBytes -= offsetBytes;

	if ((numBytes > 0) && (string[numBytes - 1] == '\t')) {
	    numBytes--;
	}













	Tk_DrawChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, string,
		numBytes, offsetX, y + baseline - sValuePtr->offset);
	if (sValuePtr->underline) {
	    Tk_UnderlineChars(display, dst, stylePtr->ulGC, sValuePtr->tkfont,
		    string, offsetX,
		    y + baseline - sValuePtr->offset,
		    0, numBytes);







>
>
>
>
>
>
>
>
>
>
>
>
>







7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
#else /* !TK_DRAW_IN_CONTEXT */
	string += offsetBytes;
	numBytes -= offsetBytes;

	if ((numBytes > 0) && (string[numBytes - 1] == '\t')) {
	    numBytes--;
	}

        /*
         * Don't draw any soft hyphen unless it is the last character
         * of the display line. Soft hyphens can only show up at the
         * end of a chunk, so test their presence at this place only.
         */

        if (chunkPtr->nextPtr != NULL) {
            if ((numBytes > 1) && (string[numBytes - 1] == '\u00AD')) {
                numBytes = numBytes - 2;
            }
        }

	Tk_DrawChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, string,
		numBytes, offsetX, y + baseline - sValuePtr->offset);
	if (sValuePtr->underline) {
	    Tk_UnderlineChars(display, dst, stylePtr->ulGC, sValuePtr->tkfont,
		    string, offsetX,
		    y + baseline - sValuePtr->offset,
		    0, numBytes);
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
 * MeasureChars --
 *
 *	Determine the number of characters from the string that will fit in
 *	the given horizontal span. The measurement is done under the
 *	assumption that Tk_DrawChars will be used to actually display the
 *	characters.
 *
 *	If tabs are encountered in the string, they will be ignored (they
 *	should only occur as last character of the string anyway).
 *
 *	If a newline is encountered in the string, the line will be broken at
 *	that point.
 *
 * Results:
 *	The return value is the number of bytes from the range of start to end
 *	in source that fit in the span given by startX and maxX. *nextXPtr is







|
|







8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
 * MeasureChars --
 *
 *	Determine the number of characters from the string that will fit in
 *	the given horizontal span. The measurement is done under the
 *	assumption that Tk_DrawChars will be used to actually display the
 *	characters.
 *
 *	If tabs or soft hyphens are encountered in the string, they will be
 *	ignored (they can only occur as last character of the string).
 *
 *	If a newline is encountered in the string, the line will be broken at
 *	that point.
 *
 * Results:
 *	The return value is the number of bytes from the range of start to end
 *	in source that fit in the span given by startX and maxX. *nextXPtr is
8588
8589
8590
8591
8592
8593
8594




8595
8596
8597
8598
8599
8600
8601
	     */

	    for (special = start; special < end; special++) {
		ch = *special;
		if ((ch == '\t') || (ch == '\n')) {
		    break;
		}




	    }
	}

	/*
	 * Special points at the next special character (or the end of the
	 * string). Process characters between start and special.
	 */







>
>
>
>







8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
	     */

	    for (special = start; special < end; special++) {
		ch = *special;
		if ((ch == '\t') || (ch == '\n')) {
		    break;
		}
                if (ch == '\u00AD') {
                    special--;
                    break;
                }
	    }
	}

	/*
	 * Special points at the next special character (or the end of the
	 * string). Process characters between start and special.
	 */
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626



8627
8628
8629
8630
8631
8632
8633
	    /*
	     * No more chars fit in line.
	     */

	    break;
	}
	if (special < end) {
	    if (ch != '\t') {
		break;
	    }



	    start++;
	}
    }

    *nextXPtr = curX;
    return start - (source+rangeStart);
}







|


>
>
>







8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
	    /*
	     * No more chars fit in line.
	     */

	    break;
	}
	if (special < end) {
	    if (ch == '\n') {
		break;
	    }
            if (ch == '\u00AD') {
                start++;
            }
	    start++;
	}
    }

    *nextXPtr = curX;
    return start - (source+rangeStart);
}