summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXFont.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tkMacOSXFont.c')
-rw-r--r--macosx/tkMacOSXFont.c210
1 files changed, 160 insertions, 50 deletions
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index 88e3593..f9cd9bc 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -112,7 +112,7 @@ static int CreateNamedSystemFont(Tcl_Interp *interp,
self = [self init];
if (self) {
Tcl_DStringInit(&_ds);
- Tcl_UtfToUniCharDString((const char *)bytes, len, &_ds);
+ Tcl_UtfToChar16DString((const char *)bytes, len, &_ds);
_string = [[NSString alloc]
initWithCharactersNoCopy:(unichar *)Tcl_DStringValue(&_ds)
length:Tcl_DStringLength(&_ds)>>1
@@ -164,9 +164,9 @@ static int CreateNamedSystemFont(Tcl_Interp *interp,
Tcl_DStringSetLength(&_ds, 3 * [_string length]);
p = Tcl_DStringValue(&_ds);
for (index = 0; index < [_string length]; index++) {
- p += Tcl_UniCharToUtf([_string characterAtIndex: index], p);
+ p += Tcl_UniCharToUtf([_string characterAtIndex: index]|TCL_COMBINE, p);
}
- Tcl_DStringSetLength(&_ds, p - Tcl_DStringValue(&_ds));
+ Tcl_DStringSetLength(&_ds, (Tcl_Size)(p - Tcl_DStringValue(&_ds)));
}
return _ds;
}
@@ -203,7 +203,8 @@ GetTkFontAttributesForNSFont(
NSFontTraitMask traits = [[NSFontManager sharedFontManager]
traitsOfFont:nsFont];
faPtr->family = Tk_GetUid([[nsFont familyName] UTF8String]);
- faPtr->size = [nsFont pointSize];
+#define FACTOR 0.75
+ faPtr->size = [nsFont pointSize] * FACTOR;
faPtr->weight = (traits & NSBoldFontMask ? TK_FW_BOLD : TK_FW_NORMAL);
faPtr->slant = (traits & NSItalicFontMask ? TK_FS_ITALIC : TK_FS_ROMAN);
@@ -242,12 +243,12 @@ FindNSFont(
NSString *family;
if (familyName) {
- family = [[[TKNSString alloc] initWithTclUtfBytes:familyName length:-1] autorelease];
+ family = [[[TKNSString alloc] initWithTclUtfBytes:familyName length:TCL_INDEX_NONE] autorelease];
} else {
family = [defaultFont familyName];
}
if (size == 0.0) {
- size = [defaultFont pointSize];
+ size = [defaultFont pointSize] * FACTOR;
}
nsFont = [fm fontWithFamily:family traits:traits weight:weight size:size];
@@ -420,6 +421,139 @@ CreateNamedSystemFont(
}
#pragma mark -
+
+#pragma mark Grapheme Cluster indexing
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * startOfClusterObjCmd --
+ *
+ * This function is invoked to process the startOfCluster command.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+startOfClusterObjCmd(
+ TCL_UNUSED(void *),
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ TKNSString *S;
+ const char *stringArg;
+ Tcl_Size len, idx;
+ if ((unsigned)(objc - 3) > 1) {
+ Tcl_WrongNumArgs(interp, 1 , objv, "str start ?locale?");
+ return TCL_ERROR;
+ }
+ stringArg = Tcl_GetStringFromObj(objv[1], &len);
+ if (stringArg == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_Size ulen = TkGetCharLength(objv[1]);
+ S = [[TKNSString alloc] initWithTclUtfBytes:stringArg length:len];
+ len = [S length];
+ if (TkGetIntForIndex(objv[2], ulen - 1, 0, &idx) != TCL_OK) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad index \"%s\": must be integer?[+-]integer?, end?[+-]integer?, or \"\"",
+ Tcl_GetString(objv[2])));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "INDEX", NULL);
+ return TCL_ERROR;
+ }
+ if (idx > 0 && len != ulen) {
+ /* The string contains codepoints > \uFFFF. Determine UTF-16 index */
+ Tcl_Size newIdx = 0;
+ for (Tcl_Size i = 0; i < idx; i++) {
+ newIdx += 1 + (((newIdx < (Tcl_Size)len-1) && ([S characterAtIndex:newIdx]&0xFC00) == 0xD800) && (([S characterAtIndex:newIdx+1]&0xFC00) == 0xDC00));
+ }
+ idx = newIdx;
+ }
+ if (idx >= 0) {
+ if (idx >= len) {
+ idx = len;
+ } else {
+ NSRange range = [S rangeOfComposedCharacterSequenceAtIndex:idx];
+ idx = range.location;
+ }
+ if (idx > 0 && len != ulen) {
+ /* The string contains codepoints > \uFFFF. Determine UTF-32 index */
+ Tcl_Size newIdx = 1;
+ for (Tcl_Size i = 1; i < idx; i++) {
+ if ((([S characterAtIndex:i-1]&0xFC00) != 0xD800) || (([S characterAtIndex:i]&0xFC00) != 0xDC00)) newIdx++;
+ }
+ idx = newIdx;
+ }
+ Tcl_SetObjResult(interp, TkNewIndexObj(idx));
+ }
+ return TCL_OK;
+}
+
+static int
+endOfClusterObjCmd(
+ TCL_UNUSED(void *),
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ TKNSString *S;
+ char *stringArg;
+ Tcl_Size idx, len;
+
+ if ((unsigned)(objc - 3) > 1) {
+ Tcl_WrongNumArgs(interp, 1 , objv, "str start ?locale?");
+ return TCL_ERROR;
+ }
+ stringArg = Tcl_GetStringFromObj(objv[1], &len);
+ if (stringArg == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_Size ulen = TkGetCharLength(objv[1]);
+ S = [[TKNSString alloc] initWithTclUtfBytes:stringArg length:len];
+ len = [S length];
+ if (TkGetIntForIndex(objv[2], ulen - 1, 0, &idx) != TCL_OK) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad index \"%s\": must be integer?[+-]integer?, end?[+-]integer?, or \"\"",
+ Tcl_GetString(objv[2])));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "INDEX", NULL);
+ return TCL_ERROR;
+ }
+ if (idx > 0 && len != ulen) {
+ /* The string contains codepoints > \uFFFF. Determine UTF-16 index */
+ Tcl_Size newIdx = 0;
+ for (Tcl_Size i = 0; i < idx; i++) {
+ newIdx += 1 + (((newIdx < len-1) && ([S characterAtIndex:newIdx]&0xFC00) == 0xD800) && (([S characterAtIndex:newIdx+1]&0xFC00) == 0xDC00));
+ }
+ idx = newIdx;
+ }
+ if (idx + 1 <= len) {
+ if (idx < 0) {
+ idx = 0;
+ } else {
+ NSRange range = [S rangeOfComposedCharacterSequenceAtIndex:idx];
+ idx = range.location + range.length;
+ if (idx > 0 && len != ulen) {
+ /* The string contains codepoints > \uFFFF. Determine UTF-32 index */
+ Tcl_Size newIdx = 1;
+ for (Tcl_Size i = 1; i < idx; i++) {
+ if ((([S characterAtIndex:i-1]&0xFC00) != 0xD800) || (([S characterAtIndex:i]&0xFC00) != 0xDC00)) newIdx++;
+ }
+ idx = newIdx;
+ }
+ }
+ Tcl_SetObjResult(interp, TkNewIndexObj(idx));
+ }
+ return TCL_OK;
+}
+
+#pragma mark -
#pragma mark Font handling:
/*
@@ -515,6 +649,8 @@ TkpFontPkgInit(
[cs release];
}
[pool drain];
+ Tcl_CreateObjCommand(interp, "::tk::startOfCluster", startOfClusterObjCmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "::tk::endOfCluster", endOfClusterObjCmd, NULL, NULL);
}
/*
@@ -612,7 +748,7 @@ TkpGetFontFromAttributes(
/* Set of attributes to match. */
{
MacFont *fontPtr;
- CGFloat points = floor(TkFontGetPoints(tkwin, faPtr->size) + 0.5);
+ CGFloat points = floor(TkFontGetPoints(tkwin, faPtr->size / FACTOR) + 0.5);
NSFontTraitMask traits = GetNSFontTraitsFromTkFontAttributes(faPtr);
NSInteger weight = (faPtr->weight == TK_FW_BOLD ? 9 : 5);
NSFont *nsFont;
@@ -701,7 +837,7 @@ TkpGetFontFamilies(
for (NSString *family in list) {
Tcl_ListObjAppendElement(NULL, resultPtr,
- Tcl_NewStringObj([family UTF8String], -1));
+ Tcl_NewStringObj([family UTF8String], TCL_INDEX_NONE));
}
Tcl_SetObjResult(interp, resultPtr);
}
@@ -741,7 +877,7 @@ TkpGetSubFonts(
if (family) {
Tcl_ListObjAppendElement(NULL, resultPtr,
- Tcl_NewStringObj([family UTF8String], -1));
+ Tcl_NewStringObj([family UTF8String], TCL_INDEX_NONE));
}
}
}
@@ -821,7 +957,7 @@ Tk_MeasureChars(
Tk_Font tkfont, /* Font in which characters will be drawn. */
const char *source, /* UTF-8 string to be displayed. Need not be
* '\0' terminated. */
- int numBytes, /* Maximum number of bytes to consider from
+ Tcl_Size numBytes, /* Maximum number of bytes to consider from
* source string. */
int maxLength, /* If >= 0, maxLength specifies the longest
* permissible line length; don't consider any
@@ -871,10 +1007,10 @@ TkpMeasureCharsInContext(
Tk_Font tkfont, /* Font in which characters will be drawn. */
const char * source, /* UTF-8 string to be displayed. Need not be
* '\0' terminated. */
- int numBytes, /* Maximum number of bytes to consider from
+ Tcl_Size numBytes, /* Maximum number of bytes to consider from
* source string in all. */
- int rangeStart, /* Index of first byte to measure. */
- int rangeLength, /* Length of range to measure in bytes. */
+ Tcl_Size rangeStart, /* Index of first byte to measure. */
+ Tcl_Size rangeLength, /* Length of range to measure in bytes. */
int maxLength, /* If >= 0, maxLength specifies the longest
* permissible line length; don't consider any
* character that would cross this x-position.
@@ -1030,7 +1166,7 @@ TkpMeasureCharsInContext(
[attributedString release];
[string release];
length = ceil(width - offset);
- fit = (TkUtfAtIndex(source, index) - source) - rangeStart;
+ fit = (Tcl_UtfAtIndex(source, index) - source) - rangeStart;
done:
#ifdef TK_MAC_DEBUG_FONTS
TkMacOSXDbgMsg("measure: source=\"%s\" range=\"%.*s\" maxLength=%d "
@@ -1079,7 +1215,7 @@ Tk_DrawChars(
* passed to this function. If they are not
* stripped out, they will be displayed as
* regular printing characters. */
- int numBytes, /* Number of bytes in string. */
+ Tcl_Size numBytes, /* Number of bytes in string. */
int x, int y) /* Coordinates at which to place origin of the
* string when drawing. */
{
@@ -1101,7 +1237,7 @@ TkDrawAngledChars(
* passed to this function. If they are not
* stripped out, they will be displayed as
* regular printing characters. */
- int numBytes, /* Number of bytes in string. */
+ Tcl_Size numBytes, /* Number of bytes in string. */
double x, double y, /* Coordinates at which to place origin of
* string when drawing. */
double angle) /* What angle to put text at, in degrees. */
@@ -1144,9 +1280,9 @@ TkpDrawCharsInContext(
* passed to this function. If they are not
* stripped out, they will be displayed as
* regular printing characters. */
- int numBytes, /* Number of bytes in string. */
- int rangeStart, /* Index of first byte to draw. */
- int rangeLength, /* Length of range to draw in bytes. */
+ Tcl_Size numBytes, /* Number of bytes in string. */
+ Tcl_Size rangeStart, /* Index of first byte to draw. */
+ Tcl_Size rangeLength, /* Length of range to draw in bytes. */
int x, int y) /* Coordinates at which to place origin of the
* whole (not just the range) string when
* drawing. */
@@ -1169,9 +1305,9 @@ TkpDrawAngledCharsInContext(
* passed to this function. If they are not
* stripped out, they will be displayed as
* regular printing characters. */
- int numBytes, /* Number of bytes in string. */
- int rangeStart, /* Index of first byte to draw. */
- int rangeLength, /* Length of range to draw in bytes. */
+ Tcl_Size numBytes, /* Number of bytes in string. */
+ Tcl_Size rangeStart, /* Index of first byte to draw. */
+ Tcl_Size rangeLength, /* Length of range to draw in bytes. */
double x, double y, /* Coordinates at which to place origin of the
* whole (not just the range) string when
* drawing. */
@@ -1305,32 +1441,6 @@ TkMacOSXNSFontAttributesForFont(
}
/*
- *---------------------------------------------------------------------------
- *
- * TkMacOSXIsCharacterMissing --
- *
- * Given a tkFont and a character determine whether the character has
- * a glyph defined in the font or not.
- *
- * Results:
- * Returns a 1 if the character is missing, a 0 if it is not.
- *
- * Side effects:
- * None.
- *
- *---------------------------------------------------------------------------
- */
-
-#undef TkMacOSXIsCharacterMissing
-int
-TkMacOSXIsCharacterMissing(
- TCL_UNUSED(Tk_Font), /* The font we are looking in. */
- TCL_UNUSED(unsigned int)) /* The character we are looking for. */
-{
- return 0;
-}
-
-/*
*----------------------------------------------------------------------
*
* TkMacOSXFontDescriptionForNSFontAndNSFontAttributes --
@@ -1363,8 +1473,8 @@ TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
id strikethrough = [nsAttributes objectForKey:
NSStrikethroughStyleAttributeName];
- objv[i++] = Tcl_NewStringObj(familyName, -1);
- objv[i++] = Tcl_NewWideIntObj((Tcl_WideInt)floor([nsFont pointSize] + 0.5));
+ objv[i++] = Tcl_NewStringObj(familyName, TCL_INDEX_NONE);
+ objv[i++] = Tcl_NewWideIntObj((Tcl_WideInt)floor([nsFont pointSize] * FACTOR + 0.5));
#define S(s) Tcl_NewStringObj(STRINGIFY(s), (sizeof(STRINGIFY(s))-1))
objv[i++] = (traits & NSBoldFontMask) ? S(bold) : S(normal);
objv[i++] = (traits & NSItalicFontMask) ? S(italic) : S(roman);