summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2003-11-21 18:51:18 (GMT)
committervincentdarley <vincentdarley>2003-11-21 18:51:18 (GMT)
commite12ef8efd22290667ca8025a561c41bd0a0dc872 (patch)
treeb496eb8e8536a2cf8b8507d74d0a2f3e4afe60eb
parentfdda3361d0bfd7bf2eaab1a47112b09989cc707a (diff)
downloadtk-e12ef8efd22290667ca8025a561c41bd0a0dc872.zip
tk-e12ef8efd22290667ca8025a561c41bd0a0dc872.tar.gz
tk-e12ef8efd22290667ca8025a561c41bd0a0dc872.tar.bz2
correct handling of interpolated tabs using fractional pixel widths
-rw-r--r--ChangeLog9
-rw-r--r--generic/tkText.c22
-rw-r--r--generic/tkText.h8
-rw-r--r--generic/tkTextDisp.c35
-rw-r--r--tests/textDisp.test34
5 files changed, 64 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog
index b7bfcd1..238519e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2003-11-21 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tkTextDisp.c:
+ * generic/tkText.h:
+ * generic/tkText.c:
+ * tests/textDisp.test: ensure interpolated tabs are at the same
+ location as the equivalent real tabs, by making use of fractional
+ rather than integer pixel calculations.
+
+2003-11-21 Vince Darley <vincentdarley@users.sourceforge.net>
+
* generic/tkTextDisp.c: prevent wrapped line height calculations
until the widget has actually been given a geometry.
diff --git a/generic/tkText.c b/generic/tkText.c
index 133d88d..c5c8baa 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -14,7 +14,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkText.c,v 1.44 2003/11/15 02:33:50 vincentdarley Exp $
+ * RCS: @(#) $Id: tkText.c,v 1.45 2003/11/21 18:51:18 vincentdarley Exp $
*/
#include "default.h"
@@ -3310,6 +3310,7 @@ TkTextGetTabs(interp, tkwin, stringPtr)
TkTextTabArray *tabArrayPtr;
TkTextTab *tabPtr;
Tcl_UniChar ch;
+ double prevStop, lastStop;
/* Map these strings to TkTextTabAlign values */
@@ -3342,6 +3343,8 @@ TkTextGetTabs(interp, tkwin, stringPtr)
tabArrayPtr = (TkTextTabArray *) ckalloc((unsigned)
(sizeof(TkTextTabArray) + (count-1)*sizeof(TkTextTab)));
tabArrayPtr->numTabs = 0;
+ prevStop = 0.0;
+ lastStop = 0.0;
for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc; i++, tabPtr++) {
int index;
@@ -3349,6 +3352,14 @@ TkTextGetTabs(interp, tkwin, stringPtr)
!= TCL_OK) {
goto error;
}
+
+ prevStop = lastStop;
+ if (Tk_GetMMFromObj(interp, tkwin, objv[i], &lastStop) != TCL_OK) {
+ goto error;
+ }
+ lastStop *= WidthOfScreen(Tk_Screen(tkwin));
+ lastStop /= WidthMMOfScreen(Tk_Screen(tkwin));
+
tabArrayPtr->numTabs++;
/*
@@ -3373,6 +3384,15 @@ TkTextGetTabs(interp, tkwin, stringPtr)
}
tabPtr->alignment = ((TkTextTabAlign)index);
}
+
+ /*
+ * For when we need to interpolate tab stops, store
+ * these two so we know the tab stop size to very
+ * high precision.
+ */
+ tabArrayPtr->lastTab = lastStop;
+ tabArrayPtr->tabIncrement = lastStop - prevStop;
+
return tabArrayPtr;
error:
diff --git a/generic/tkText.h b/generic/tkText.h
index ee19ad2..bf79bc7 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkText.h,v 1.21 2003/11/15 02:33:50 vincentdarley Exp $
+ * RCS: @(#) $Id: tkText.h,v 1.22 2003/11/21 18:51:18 vincentdarley Exp $
*/
#ifndef _TKTEXT
@@ -474,6 +474,12 @@ typedef struct TkTextTab {
typedef struct TkTextTabArray {
int numTabs; /* Number of tab stops. */
+ double lastTab; /* The accurate fractional pixel
+ * position of the last tab. */
+ double tabIncrement; /* The accurate fractional pixel
+ * increment between interpolated
+ * tabs we have to create when
+ * we exceed numTabs. */
TkTextTab tabs[1]; /* Array of tabs. The actual size
* will be numTabs. THIS FIELD MUST
* BE THE LAST IN THE STRUCTURE. */
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 623570a..b218a79 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextDisp.c,v 1.34 2003/11/21 17:29:13 vincentdarley Exp $
+ * RCS: @(#) $Id: tkTextDisp.c,v 1.35 2003/11/21 18:51:18 vincentdarley Exp $
*/
#include "tkPort.h"
@@ -6596,7 +6596,7 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
int x, desired, delta, width, decimal, i, gotDigit;
TkTextDispChunk *chunkPtr2, *decimalChunkPtr;
CharInfo *ciPtr;
- int tabX, prev, spaceWidth;
+ int tabX, spaceWidth;
char *p;
TkTextTabAlign alignment;
@@ -6633,15 +6633,10 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
* from the last two tab positions.
*/
- if (tabArrayPtr->numTabs > 1) {
- prev = tabArrayPtr->tabs[tabArrayPtr->numTabs-2].location;
- } else {
- prev = 0;
- }
+ tabX = (int) (tabArrayPtr->lastTab
+ + (index + 1 - tabArrayPtr->numTabs)
+ * tabArrayPtr->tabIncrement + 0.5);
alignment = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].alignment;
- tabX = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location
- + (index + 1 - tabArrayPtr->numTabs)
- * (tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location - prev);
}
if (alignment == LEFT) {
@@ -6780,7 +6775,7 @@ SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX)
int maxX; /* X-location of pixel just past the
* right edge of the line. */
{
- int tabX, prev, result, index, spaceWidth;
+ int tabX, result, index, spaceWidth;
TkTextTabAlign alignment;
index = *indexPtr;
@@ -6796,7 +6791,7 @@ SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX)
do {
/*
- * We were given the count before this tabs, so increment it
+ * We were given the count before this tab, so increment it
* first.
*/
index++;
@@ -6805,18 +6800,12 @@ SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX)
alignment = tabArrayPtr->tabs[index].alignment;
} else {
/*
- * Ran out of tab stops; compute a tab position by extrapolating
- * from the last two tab positions.
+ * Ran out of tab stops; compute a tab position by
+ * extrapolating.
*/
-
- if (tabArrayPtr->numTabs > 1) {
- prev = tabArrayPtr->tabs[tabArrayPtr->numTabs-2].location;
- } else {
- prev = 0;
- }
- tabX = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location
- + (index + 1 - tabArrayPtr->numTabs)
- * (tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location - prev);
+ tabX = (int) (tabArrayPtr->lastTab
+ + (index + 1 - tabArrayPtr->numTabs)
+ * tabArrayPtr->tabIncrement + 0.5);
alignment = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].alignment;
}
/*
diff --git a/tests/textDisp.test b/tests/textDisp.test
index 48a4567..31abdd1 100644
--- a/tests/textDisp.test
+++ b/tests/textDisp.test
@@ -6,7 +6,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: textDisp.test,v 1.21 2003/11/21 17:29:13 vincentdarley Exp $
+# RCS: @(#) $Id: textDisp.test,v 1.22 2003/11/21 18:51:18 vincentdarley Exp $
package require tcltest 2.1
eval tcltest::configure $argv
@@ -3166,27 +3166,23 @@ test textDisp-27.7 {SizeOfTab procedure, center alignment, wrap -none (potential
lset res 0 [expr {[lindex $res 0] - $tab}]
set res
} [list 0 [expr {$fixedDiff + 18}] 7 $fixedHeight]
-test textDisp-27.7.1 {SizeOfTab procedure, fractional tab interpolation problem} {knownBug textfonts} {
+test textDisp-27.7.1 {SizeOfTab procedure, fractional tab interpolation problem} {
.t delete 1.0 end
- set cm [winfo fpixels .t 1c]
- .t configure -tabs {1c 2c 3c 4c} -wrap none -width 40
- .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd
- set width [expr {$fixedWidth * 19}]
- set tab $cm
- while {$tab < $width} {
- set tab [expr {$tab + $cm}]
+ set interpolatetab {1c 2c}
+ set precisetab {}
+ for {set i 1} {$i < 20} {incr i} {
+ lappend precisetab "${i}c"
}
- # Now we've calculated to the end of the tab after 'a', add one
- # more for 'bb\t' and we're there, with 4 for the border
- set tab [expr {4 + int($tab + $cm)}]
+ .t configure -tabs $interpolatetab -wrap none -width 150
+ .t insert 1.0 [string repeat "a\t" 20]
update
- set res [.t bbox 2.23]
- # Now, on some platforms Tk interpolated from 3c-4c->5c but that
- # interpolation doesn't use fractional pixels and so this result
- # might be off by one.
- lset res 0 [expr {[lindex $res 0] - $tab}]
- set res
-} [list 0 [expr {$fixedDiff + 18}] 7 $fixedHeight]
+ set res [.t bbox 1.20]
+ # Now, Tk's interpolated tabs should be the same as
+ # non-interpolated.
+ .t configure -tabs $precisetab
+ update
+ expr {[lindex $res 0] - [lindex [.t bbox 1.20] 0]}
+} {0}
.t configure -wrap char -tabs {} -width 20
update