summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXFont.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tkMacOSXFont.c')
-rw-r--r--macosx/tkMacOSXFont.c2578
1 files changed, 778 insertions, 1800 deletions
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index b09e62e..ae3be92 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -4,10 +4,9 @@
* Contains the Macintosh implementation of the platform-independant
* font package interface.
*
- * Copyright (c) 1990-1994 The Regents of the University of California.
- * Copyright (c) 1994-1997 Sun Microsystems, Inc.
- * Copyright 2001, Apple Computer, Inc.
- * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright 2002-2004 Benjamin Riefenstahl, Benjamin.Riefenstahl@epost.de
+ * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright 2008-2009, Apple Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -16,248 +15,319 @@
#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"
-#include "tclInt.h" /* for Tcl_CreateNamespace() */
-
/*
- * Dealing with pascal strings.
- */
-
-#ifndef StrLength
-#define StrLength(s) (*((unsigned char *) (s)))
-#endif
-#ifndef StrBody
-#define StrBody(s) ((char *) (s) + 1)
+#ifdef TK_MAC_DEBUG
+#define TK_MAC_DEBUG_FONTS
#endif
-#define pstrcmp(s1, s2) RelString((s1), (s2), 1, 1)
-#define pstrcasecmp(s1, s2) RelString((s1), (s2), 0, 1)
+*/
/*
- * The preferred font encodings.
+ * The following structure represents our Macintosh-specific implementation
+ * of a font object.
*/
-static const char *encodingList[] = {
- "macRoman", "macJapan", NULL
-};
-
-/*
- * The following structures are used to map the script/language codes of a
- * font to the name that should be passed to Tcl_GetTextEncoding() to obtain
- * the encoding for that font. The set of numeric constants is fixed and
- * defined by Apple.
- */
-
-static TkStateMap scriptMap[] = {
- {smRoman, "macRoman"},
- {smJapanese, "macJapan"},
- {smTradChinese, "macChinese"},
- {smKorean, "macKorean"},
- {smArabic, "macArabic"},
- {smHebrew, "macHebrew"},
- {smGreek, "macGreek"},
- {smCyrillic, "macCyrillic"},
- {smRSymbol, "macRSymbol"},
- {smDevanagari, "macDevanagari"},
- {smGurmukhi, "macGurmukhi"},
- {smGujarati, "macGujarati"},
- {smOriya, "macOriya"},
- {smBengali, "macBengali"},
- {smTamil, "macTamil"},
- {smTelugu, "macTelugu"},
- {smKannada, "macKannada"},
- {smMalayalam, "macMalayalam"},
- {smSinhalese, "macSinhalese"},
- {smBurmese, "macBurmese"},
- {smKhmer, "macKhmer"},
- {smThai, "macThailand"},
- {smLaotian, "macLaos"},
- {smGeorgian, "macGeorgia"},
- {smArmenian, "macArmenia"},
- {smSimpChinese, "macSimpChinese"},
- {smTibetan, "macTIbet"},
- {smMongolian, "macMongolia"},
- {smGeez, "macEthiopia"},
- {smEastEurRoman, "macCentEuro"},
- {smVietnamese, "macVietnam"},
- {smExtArabic, "macSindhi"},
- {0, NULL}
-};
-
-static TkStateMap romanMap[] = {
- {langCroatian, "macCroatian"},
- {langSlovenian, "macCroatian"},
- {langIcelandic, "macIceland"},
- {langRomanian, "macRomania"},
- {langTurkish, "macTurkish"},
- {langGreek, "macGreek"},
- {0, NULL}
-};
-
-static TkStateMap cyrillicMap[] = {
- {langUkrainian, "macUkraine"},
- {langBulgarian, "macBulgaria"},
- {0, NULL}
-};
-
-/*
- * The following structure represents a font family. It is assumed that
- * all screen fonts constructed from the same "font family" share certain
- * properties; all screen fonts with the same "font family" point to a
- * shared instance of this structure. The most important shared property
- * is the character existence metrics, used to determine if a screen font
- * can display a given Unicode character.
- *
- * Under Macintosh, a "font family" is uniquely identified by its face number.
- */
-
-
-#define FONTMAP_SHIFT 10
-
-#define FONTMAP_PAGES (1 << (sizeof(Tcl_UniChar) * 8 - 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. */
- /*
- * Key.
- */
-
- FMFontFamily faceNum; /* Unique face number key for this FontFamily. */
-
- /*
- * Derived properties.
- */
-
- Tcl_Encoding encoding; /* Encoding for this font family. */
- int isSymbolFont; /* Non-zero if this is a symbol family. */
- int isMultiByteFont; /* Non-zero if this is a multi-byte family. */
- char typeTable[256]; /* Table that identfies all lead bytes for a
- * multi-byte family, used when measuring chars.
- * If a byte is a lead byte, the value at the
- * corresponding position in the typeTable is 1,
- * otherwise 0. If this is a single-byte font,
- * all entries are 0. */
- char *fontMap[FONTMAP_PAGES];
- /* Two-level sparse table used to determine
- * quickly if the specified character exists.
- * As characters are encountered, more pages
- * in this table are dynamically added. The
- * contents of each page is a bitmask
- * consisting of FONTMAP_BITSPERPAGE bits,
- * representing whether this font can be used
- * to display the given character at the
- * corresponding bit position. The high bits
- * of the character are used to pick which
- * page of the table is used. */
-} FontFamily;
-
-/*
- * The following structure encapsulates an individual screen font. A font
- * object is made up of however many SubFonts are necessary to display a
- * stream of multilingual characters.
- */
-
-typedef struct SubFont {
- char **fontMap; /* Pointer to font map from the FontFamily,
- * cached here to save a dereference. */
- FontFamily *familyPtr; /* The FontFamily for this SubFont. */
-} SubFont;
-
-/*
- * The following structure represents Macintosh's implementation of a font
- * object.
- */
-
-#define SUBFONT_SPACE 3
-
-typedef struct MacFont {
+typedef struct {
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. */
- int numSubFonts; /* Length of following array. */
- SubFont *subFontArray; /* Array of SubFonts that have been loaded
- * in order to draw/measure all the characters
- * encountered by this font so far. All fonts
- * start off with one SubFont initialized by
- * AllocFont() from the original set of font
- * attributes. Usually points to
- * staticSubFonts, but may point to malloced
- * space if there are lots of SubFonts. */
- short size; /* Font size in pixels, constructed from
- * font attributes. */
- short style; /* Style bits, constructed from font
- * attributes. */
+ NSFont *nsFont;
+ NSDictionary *nsAttributes;
} MacFont;
/*
- * The following structure is used to map between the UTF-8 name for a font and
- * the name that the Macintosh uses to refer to the font, in order to determine
- * if a font exists. The Macintosh names for fonts are stored in the encoding
- * of the font itself.
+ * The names for our "native" fonts.
*/
-typedef struct FontNameMap {
- Tk_Uid utfName; /* The name of the font in UTF-8. */
- StringPtr nativeName; /* The name of the font in the font's encoding. */
- FMFontFamily faceNum; /* Unique face number for this font. */
-} FontNameMap;
+#define SYSTEMFONT_NAME "system"
+#define APPLFONT_NAME "application"
+#define MENUITEMFONT_NAME "menu"
+
+struct SystemFontMapEntry {
+ const ThemeFontID id;
+ const char *systemName;
+ const char *tkName;
+ const char *tkName1;
+};
+#define ThemeFont(n, ...) { kTheme##n##Font, "system" #n "Font", ##__VA_ARGS__ }
+static const struct SystemFontMapEntry systemFontMap[] = {
+ ThemeFont(System, "TkDefaultFont", "TkIconFont"),
+ ThemeFont(EmphasizedSystem, "TkCaptionFont"),
+ ThemeFont(SmallSystem, "TkHeadingFont", "TkTooltipFont"),
+ ThemeFont(SmallEmphasizedSystem),
+ ThemeFont(Application, "TkTextFont"),
+ ThemeFont(Label, "TkSmallCaptionFont"),
+ ThemeFont(Views),
+ ThemeFont(MenuTitle),
+ ThemeFont(MenuItem, "TkMenuFont"),
+ ThemeFont(MenuItemMark),
+ ThemeFont(MenuItemCmdKey),
+ ThemeFont(WindowTitle),
+ ThemeFont(PushButton),
+ ThemeFont(UtilityWindowTitle),
+ ThemeFont(AlertHeader),
+ ThemeFont(Toolbar),
+ ThemeFont(MiniSystem),
+ { kThemeSystemFontDetail, "systemDetailSystemFont" },
+ { kThemeSystemFontDetailEmphasized, "systemDetailEmphasizedSystemFont" },
+ { -1, NULL }
+};
+#undef ThemeFont
+
+static int antialiasedTextEnabled = -1;
+static NSCharacterSet *whitespaceCharacterSet = nil;
+static NSCharacterSet *lineendingCharacterSet = nil;
+
+static void GetTkFontAttributesForNSFont(NSFont *nsFont,
+ TkFontAttributes *faPtr);
+static NSFont *FindNSFont(const char *familyName, NSFontTraitMask traits,
+ NSInteger weight, CGFloat size, int fallbackToDefault);
+static void InitFont(NSFont *nsFont, const TkFontAttributes *reqFaPtr,
+ MacFont * fontPtr);
+static int CreateNamedSystemFont(Tcl_Interp *interp, Tk_Window tkwin,
+ const char* name, TkFontAttributes *faPtr);
+static void DrawCharsInContext(Display *display, Drawable drawable, GC gc,
+ Tk_Font tkfont, const char *source, int numBytes, int rangeStart,
+ int rangeLength, int x, int y, double angle);
+
+@interface NSFont(TKFont)
+- (NSFont *)bestMatchingFontForCharacters:(const UTF16Char *)characters
+ length:(NSUInteger)length attributes:(NSDictionary *)attributes
+ actualCoveredLength:(NSUInteger *)coveredLength;
+@end
+
+#pragma mark -
+#pragma mark Font Helpers:
+
+#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
+ ((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
+ ((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask)
+
/*
- * The list of font families that are currently loaded. As screen fonts
- * are loaded, this list grows to hold information about what characters
- * exist in each font family.
+ *---------------------------------------------------------------------------
+ *
+ * GetTkFontAttributesForNSFont --
+ *
+ * Fill in TkFontAttributes for given NSFont.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
*/
-static FontFamily *fontFamilyList = NULL;
+static void
+GetTkFontAttributesForNSFont(
+ NSFont *nsFont,
+ TkFontAttributes *faPtr)
+{
+ NSFontTraitMask traits = [[NSFontManager sharedFontManager]
+ traitsOfFont:nsFont];
+ faPtr->family = Tk_GetUid([[nsFont familyName] UTF8String]);
+ faPtr->size = [nsFont pointSize];
+ faPtr->weight = (traits & NSBoldFontMask ? TK_FW_BOLD : TK_FW_NORMAL);
+ faPtr->slant = (traits & NSItalicFontMask ? TK_FS_ITALIC : TK_FS_ROMAN);
+}
+
/*
- * Information cached about the system at startup time.
+ *---------------------------------------------------------------------------
+ *
+ * FindNSFont --
+ *
+ * Find NSFont for given attributes. Use default values for missing
+ * attributes, and do a case-insensitive search for font family names
+ * if necessary. If fallbackToDefault flag is set, use the system font
+ * as a last resort.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
*/
-static FontNameMap *gFontNameMap = NULL;
-static GWorldPtr gWorld = NULL;
+static NSFont *
+FindNSFont(
+ const char *familyName,
+ NSFontTraitMask traits,
+ NSInteger weight,
+ CGFloat size,
+ int fallbackToDefault)
+{
+ NSFontManager *fm = [NSFontManager sharedFontManager];
+ NSFont *nsFont, *dflt = nil;
+ #define defaultFont (dflt ? dflt : (dflt = [NSFont systemFontOfSize:0]))
+ NSString *family;
+ if (familyName) {
+ family = [[[NSString alloc] initWithUTF8String:familyName] autorelease];
+ } else {
+ family = [defaultFont familyName];
+ }
+ if (size == 0.0) {
+ size = [defaultFont pointSize];
+ }
+ nsFont = [fm fontWithFamily:family traits:traits weight:weight size:size];
+ if (!nsFont) {
+ NSArray *availableFamilies = [fm availableFontFamilies];
+ NSString *caseFamily = nil;
+
+ for (NSString *f in availableFamilies) {
+ if ([family caseInsensitiveCompare:f] == NSOrderedSame) {
+ caseFamily = f;
+ break;
+ }
+ }
+ if (caseFamily) {
+ nsFont = [fm fontWithFamily:caseFamily traits:traits weight:weight
+ size:size];
+ }
+ }
+ if (!nsFont) {
+ nsFont = [NSFont fontWithName:family size:size];
+ }
+ if (!nsFont && fallbackToDefault) {
+ nsFont = [fm convertFont:defaultFont toFamily:family];
+ nsFont = [fm convertFont:nsFont toSize:size];
+ nsFont = [fm convertFont:nsFont toHaveTrait:traits];
+ }
+ #undef defaultFont
+ return nsFont;
+}
+
/*
- * The names for our "native" fonts.
+ *---------------------------------------------------------------------------
+ *
+ * InitFont --
+ *
+ * Helper for TkpGetNativeFont() and TkpGetFontFromAttributes().
+ *
+ * Results:
+ * Fills the MacFont structure.
+ *
+ * Side effects:
+ * Memory allocated.
+ *
+ *---------------------------------------------------------------------------
*/
-#define SYSTEMFONT_NAME "system"
-#define APPLFONT_NAME "application"
-#define MENUITEMFONT_NAME "menu"
+static void
+InitFont(
+ NSFont *nsFont,
+ const TkFontAttributes *reqFaPtr, /* Can be NULL */
+ MacFont *fontPtr)
+{
+ TkFontAttributes *faPtr;
+ TkFontMetrics *fmPtr;
+ NSDictionary *nsAttributes;
+ NSRect bounds;
+ CGFloat kern = 0.0;
+ NSFontRenderingMode renderingMode = NSFontDefaultRenderingMode;
+ int ascent, descent/*, dontAA*/;
+ static const UniChar ch[] = {'.', 'W', ' ', 0xc4, 0xc1, 0xc2, 0xc3, 0xc7};
+ /* ., W, Space, Auml, Aacute, Acirc, Atilde, Ccedilla */
+ #define nCh (sizeof(ch) / sizeof(UniChar))
+ CGGlyph glyphs[nCh];
+ CGRect boundingRects[nCh];
+
+ fontPtr->font.fid = (Font) fontPtr;
+ faPtr = &fontPtr->font.fa;
+ if (reqFaPtr) {
+ *faPtr = *reqFaPtr;
+ } else {
+ TkInitFontAttributes(faPtr);
+ }
+ fontPtr->nsFont = nsFont;
+ // some don't like antialiasing on fixed-width even if bigger than limit
+// dontAA = [nsFont isFixedPitch] && fontPtr->font.fa.size <= 10;
+ if (antialiasedTextEnabled >= 0/* || dontAA*/) {
+ renderingMode = (antialiasedTextEnabled == 0/* || dontAA*/) ?
+ NSFontIntegerAdvancementsRenderingMode :
+ NSFontAntialiasedRenderingMode;
+ }
+ nsFont = [nsFont screenFontWithRenderingMode:renderingMode];
+ GetTkFontAttributesForNSFont(nsFont, faPtr);
+ fmPtr = &fontPtr->font.fm;
+ fmPtr->ascent = floor([nsFont ascender] + [nsFont leading] + 0.5);
+ fmPtr->descent = floor(-[nsFont descender] + 0.5);
+ fmPtr->maxWidth = [nsFont maximumAdvancement].width;
+ fmPtr->fixed = [nsFont isFixedPitch]; /* Does not work for all fonts */
+
+ /*
+ * The ascent, descent and fixed fields are not correct for all fonts, as
+ * a workaround deduce that info from the metrics of some typical glyphs,
+ * along with screenfont kerning (space advance difference to printer font)
+ */
+ bounds = [nsFont boundingRectForFont];
+ if (CTFontGetGlyphsForCharacters((CTFontRef) nsFont, ch, glyphs, nCh)) {
+ fmPtr->fixed = [nsFont advancementForGlyph:glyphs[0]].width ==
+ [nsFont advancementForGlyph:glyphs[1]].width;
+ bounds = NSRectFromCGRect(CTFontGetBoundingRectsForGlyphs((CTFontRef)
+ nsFont, kCTFontDefaultOrientation, ch, boundingRects, nCh));
+ kern = [nsFont advancementForGlyph:glyphs[2]].width -
+ [fontPtr->nsFont advancementForGlyph:glyphs[2]].width;
+ }
+ descent = floor(-bounds.origin.y + 0.5);
+ ascent = floor(bounds.size.height + bounds.origin.y + 0.5);
+ if (ascent > fmPtr->ascent) {
+ fmPtr->ascent = ascent;
+ }
+ if (descent > fmPtr->descent) {
+ fmPtr->descent = descent;
+ }
+ nsAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
+ nsFont, NSFontAttributeName,
+ [NSNumber numberWithInt:faPtr->underline ?
+ NSUnderlineStyleSingle|NSUnderlinePatternSolid :
+ NSUnderlineStyleNone], NSUnderlineStyleAttributeName,
+ [NSNumber numberWithInt:faPtr->overstrike ?
+ NSUnderlineStyleSingle|NSUnderlinePatternSolid :
+ NSUnderlineStyleNone], NSStrikethroughStyleAttributeName,
+ [NSNumber numberWithInt:fmPtr->fixed ? 0 : 1],
+ NSLigatureAttributeName,
+ [NSNumber numberWithDouble:kern], NSKernAttributeName, nil];
+ fontPtr->nsAttributes = TkMacOSXMakeUncollectableAndRetain(nsAttributes);
+ #undef nCh
+}
+
/*
- * Procedures used only in this file.
+ *-------------------------------------------------------------------------
+ *
+ * CreateNamedSystemFont --
+ *
+ * Register a system font with the Tk named font mechanism.
+ *
+ * Results:
+ *
+ * Result from TkCreateNamedFont().
+ *
+ * Side effects:
+ *
+ * A new named font is added to the Tk font registry.
+ *
+ *-------------------------------------------------------------------------
*/
-static FontFamily * AllocFontFamily(const MacFont *fontPtr, int family);
-static SubFont * CanUseFallback(MacFont *fontPtr, const char *fallbackName, int ch, SubFont **fixSubFontPtrPtr);
-static SubFont * CanUseFallbackWithAliases(MacFont *fontPtr, const char *faceName, int ch, Tcl_DString *nameTriedPtr, SubFont **fixSubFontPtrPtr);
-static SubFont * FindSubFontForChar(MacFont *fontPtr, int ch, SubFont **fixSubFontPtrPtr);
-static void FontMapInsert(SubFont *subFontPtr, int ch);
-static void FontMapLoadPage(SubFont *subFontPtr, int row);
-static int FontMapLookup(SubFont *subFontPtr, int ch);
-static void FreeFontFamily(FontFamily *familyPtr);
-static void InitFont(Tk_Window tkwin, int family, unsigned char *familyName, int size, int style, MacFont *fontPtr);
-static void InitSubFont(const MacFont *fontPtr, int family, SubFont *subFontPtr);
-static void MultiFontDrawText(MacFont *fontPtr, const char *source, int numBytes, int x, int y);
-static void ReleaseFont(MacFont *fontPtr);
-static void ReleaseSubFont(SubFont *subFontPtr);
-static int SeenName(const char *name, Tcl_DString *dsPtr);
-
-static const char * BreakLine(FontFamily *familyPtr, int flags, const char *source, int numBytes, int *widthPtr);
-static int GetFamilyNum(const char *faceName, short *familyPtr);
-static int GetFamilyOrAliasNum(const char *faceName, short *familyPtr);
-static Tcl_Encoding GetFontEncoding(int faceNum, int allowSymbol, int *isSymbolPtr);
-static Tk_Uid GetUtfFaceName(StringPtr faceNameStr);
-static OSStatus GetThemeFontAndFamily(const ThemeFontID themeFontId,
- FMFontFamily *fontFamily, unsigned char *fontName, SInt16 *fontSize,
- Style *fontStyle);
+static int
+CreateNamedSystemFont(
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ const char* name,
+ TkFontAttributes *faPtr)
+{
+ TkDeleteNamedFont(NULL, tkwin, name);
+ return TkCreateNamedFont(interp, tkwin, name, faPtr);
+}
+#pragma mark -
+#pragma mark Font handling:
/*
*-------------------------------------------------------------------------
@@ -267,12 +337,13 @@ static OSStatus GetThemeFontAndFamily(const ThemeFontID themeFontId,
* This procedure is called when an application is created. It
* initializes all the structures that are used by the
* platform-dependant code on a per application basis.
+ * Note that this is called before TkpInit() !
*
* Results:
* None.
*
* Side effects:
- * See comments below.
+ * Initialize named system fonts.
*
*-------------------------------------------------------------------------
*/
@@ -281,139 +352,57 @@ void
TkpFontPkgInit(
TkMainInfo *mainPtr) /* The application being created. */
{
- FMFontFamilyIterator fontFamilyIterator;
- FMFontFamily fontFamily;
- FontNameMap *tmpFontNameMap, *newFontNameMap, *mapPtr;
- int i, j, numFonts, fontMapOffset, isSymbol;
- Str255 nativeName;
- Tcl_DString ds;
- Tcl_Encoding encoding;
- Tcl_Encoding *encodings;
-
- if (gWorld == NULL) {
- Rect rect = {0, 0, 1, 1};
-
- SetFractEnable(0);
- /*
- * Used for saving and restoring state while drawing and measuring.
- */
- if (ChkErr(NewGWorld, &gWorld, 32, &rect, NULL, NULL, 0
-#ifdef __LITTLE_ENDIAN__
- | kNativeEndianPixMap
-#endif
- ) != noErr) {
- Tcl_Panic("TkpFontPkgInit: NewGWorld failed");
- }
- /*
- * The name of each font is stored in the encoding of that font.
- * How would we translate a name from UTF-8 into the native encoding
- * of the font unless we knew the encoding of that font? We can't.
- * So, precompute the UTF-8 and native names of all fonts on the
- * system. The when the user asks for font by its UTF-8 name, we
- * lookup the name in that table and really ask for the font by its
- * native name. Any unknown UTF-8 names will be mapped to the system
- * font.
- */
- FMCreateFontFamilyIterator(NULL, NULL, kFMDefaultOptions, &fontFamilyIterator);
- numFonts = 0;
- while (FMGetNextFontFamily(&fontFamilyIterator, &fontFamily) != kFMIterationCompleted) {
- numFonts++;
- }
- tmpFontNameMap = (FontNameMap *) ckalloc(sizeof(FontNameMap) * numFonts);
- encodings = (Tcl_Encoding *) ckalloc(sizeof(Tcl_Encoding) * numFonts);
- mapPtr = tmpFontNameMap;
- FMResetFontFamilyIterator(NULL, NULL, kFMDefaultOptions, &fontFamilyIterator);
- i = 0;
- while (FMGetNextFontFamily(&fontFamilyIterator, &fontFamily) != kFMIterationCompleted) {
- mapPtr->faceNum = fontFamily;
- encodings[i] = GetFontEncoding(mapPtr->faceNum, 0, &isSymbol);
- FMGetFontFamilyName(fontFamily, nativeName );
- Tcl_ExternalToUtfDString(encodings[i], StrBody(nativeName), StrLength(nativeName), &ds);
- mapPtr->utfName = Tk_GetUid(Tcl_DStringValue(&ds));
- mapPtr->nativeName = (StringPtr) ckalloc(StrLength(nativeName) + 1);
- memcpy(mapPtr->nativeName, nativeName, StrLength(nativeName) + 1);
- Tcl_DStringFree(&ds);
- mapPtr++;
- i++;
- }
- FMDisposeFontFamilyIterator(&fontFamilyIterator);
-
- /*
- * Reorder FontNameMap so fonts with the preferred encodings are at
- * the front of the list. The relative order of fonts that all have
- * the same encoding is preserved. Fonts with unknown encodings get
- * stuck at the end.
- */
- newFontNameMap = (FontNameMap *) ckalloc(sizeof(FontNameMap) * (numFonts + 1));
- fontMapOffset = 0;
- for (i = 0; encodingList[i] != NULL; i++) {
- encoding = Tcl_GetEncoding(NULL, encodingList[i]);
- if (encoding == NULL) {
- continue;
- }
- for (j = 0; j < numFonts; j++) {
- if (encodings[j] == encoding) {
- newFontNameMap[fontMapOffset] = tmpFontNameMap[j];
- fontMapOffset++;
- Tcl_FreeEncoding(encodings[j]);
- tmpFontNameMap[j].utfName = NULL;
- }
+ Tcl_Interp *interp = mainPtr->interp;
+ Tk_Window tkwin = (Tk_Window) mainPtr->winPtr;
+ const struct SystemFontMapEntry *systemFont = systemFontMap;
+ NSFont *nsFont;
+ TkFontAttributes fa;
+ NSMutableCharacterSet *cs;
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+
+ /* force this for now */
+ if (!mainPtr->winPtr->mainPtr) {
+ mainPtr->winPtr->mainPtr = mainPtr;
+ }
+ while (systemFont->systemName) {
+ nsFont = (NSFont*) CTFontCreateUIFontForLanguage(
+ HIThemeGetUIFontType(systemFont->id), 0, NULL);
+ if (nsFont) {
+ TkInitFontAttributes(&fa);
+ GetTkFontAttributesForNSFont(nsFont, &fa);
+ CreateNamedSystemFont(interp, tkwin, systemFont->systemName, &fa);
+ if (systemFont->tkName) {
+ CreateNamedSystemFont(interp, tkwin, systemFont->tkName, &fa);
}
- Tcl_FreeEncoding(encoding);
- }
- for (i = 0; i < numFonts; i++) {
- if (tmpFontNameMap[i].utfName != NULL) {
- newFontNameMap[fontMapOffset] = tmpFontNameMap[i];
- fontMapOffset++;
- Tcl_FreeEncoding(encodings[i]);
+ if (systemFont->tkName1) {
+ CreateNamedSystemFont(interp, tkwin, systemFont->tkName1, &fa);
}
+ CFRelease(nsFont);
}
- if (fontMapOffset != numFonts) {
- Tcl_Panic("TkpFontPkgInit: unexpected number of fonts");
- }
-
- mapPtr = &newFontNameMap[numFonts];
- mapPtr->utfName = NULL;
- mapPtr->nativeName = NULL;
- mapPtr->faceNum = 0;
-
- ckfree((char *) tmpFontNameMap);
- ckfree((char *) encodings);
-
- gFontNameMap = newFontNameMap;
+ systemFont++;
}
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * GetThemeFontAndFamily --
- *
- * Wrapper around the GetThemeFont and FMGetFontFamilyFromName APIs.
- *
- *---------------------------------------------------------------------------
- */
-
-OSStatus
-GetThemeFontAndFamily(
- const ThemeFontID themeFontId,
- FMFontFamily* fontFamily,
- unsigned char *fontName,
- SInt16 *fontSize,
- Style *fontStyle)
-{
- OSStatus err = ChkErr(GetThemeFont, themeFontId, smSystemScript, fontName,
- fontSize, fontStyle);
-
- if (err == noErr) {
- *fontFamily = FMGetFontFamilyFromName(fontName);
- if (*fontFamily == kInvalidFontFamily) {
- err = kFMInvalidFontFamilyErr;
- TkMacOSXDbgMsg("FMGetFontFamilyFromName failed.");
- }
+ TkInitFontAttributes(&fa);
+ nsFont = (NSFont*) CTFontCreateUIFontForLanguage(
+ kCTFontUserFixedPitchFontType, 11, NULL);
+ if (nsFont) {
+ GetTkFontAttributesForNSFont(nsFont, &fa);
+ CFRelease(nsFont);
+ } else {
+ fa.family = Tk_GetUid("Monaco");
+ fa.size = 11;
+ fa.weight = TK_FW_NORMAL;
+ fa.slant = TK_FS_ROMAN;
}
-
- return err;
+ CreateNamedSystemFont(interp, tkwin, "TkFixedFont", &fa);
+ if (!whitespaceCharacterSet) {
+ whitespaceCharacterSet = [[NSCharacterSet
+ whitespaceAndNewlineCharacterSet] retain];
+ cs = [whitespaceCharacterSet mutableCopy];
+ [cs removeCharactersInString:@" "];
+ lineendingCharacterSet = [cs copy];
+ [cs release];
+ }
+ [pool drain];
}
/*
@@ -445,14 +434,11 @@ GetThemeFontAndFamily(
TkFont *
TkpGetNativeFont(
Tk_Window tkwin, /* For display where font will be used. */
- CONST char *name) /* Platform-specific font name. */
+ const char *name) /* Platform-specific font name. */
{
+ MacFont *fontPtr = NULL;
ThemeFontID themeFontId;
- FMFontFamily fontFamily;
- Str255 fontName;
- SInt16 fontSize;
- Style fontStyle;
- MacFont * fontPtr;
+ CTFontRef ctFont;
if (strcmp(name, SYSTEMFONT_NAME) == 0) {
themeFontId = kThemeSystemFont;
@@ -463,14 +449,13 @@ TkpGetNativeFont(
} else {
return NULL;
}
- if (GetThemeFontAndFamily(themeFontId, &fontFamily, fontName, &fontSize,
- &fontStyle) != noErr) {
- return NULL;
+ ctFont = CTFontCreateUIFontForLanguage(HIThemeGetUIFontType(
+ themeFontId), 0, NULL);
+ if (ctFont) {
+ fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
+ InitFont((NSFont*) ctFont, NULL, fontPtr);
}
- fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
- InitFont(tkwin, fontFamily, fontName, fontSize, fontStyle, fontPtr);
-
return (TkFont *) fontPtr;
}
@@ -512,64 +497,37 @@ TkpGetFontFromAttributes(
* will be released. If NULL, a new TkFont
* structure is allocated. */
Tk_Window tkwin, /* For display where font will be used. */
- CONST TkFontAttributes *faPtr)
+ const TkFontAttributes *faPtr)
/* Set of attributes to match. */
{
- short faceNum, style;
- int i, j;
- const char *faceName, *fallback;
- char ***fallbacks;
MacFont *fontPtr;
+ int points = TkFontGetPoints(tkwin, faPtr->size);
+ NSFontTraitMask traits = GetNSFontTraitsFromTkFontAttributes(faPtr);
+ NSInteger weight = (faPtr->weight == TK_FW_BOLD ? 9 : 5);
+ NSFont *nsFont;
- /*
- * Algorithm to get the closest font to the one requested.
- *
- * try fontname
- * try all aliases for fontname
- * foreach fallback for fontname
- * try the fallback
- * try all aliases for the fallback
- */
+ nsFont = FindNSFont(faPtr->family, traits, weight, points, 0);
+ if (!nsFont) {
+ char *const *aliases = TkFontGetAliasList(faPtr->family);
- faceNum = 0;
- faceName = faPtr->family;
- if (faceName != NULL) {
- if (GetFamilyOrAliasNum(faceName, &faceNum) != 0) {
- goto found;
- }
- fallbacks = TkFontGetFallbacks();
- for (i = 0; fallbacks[i] != NULL; i++) {
- for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) {
- if (strcasecmp(faceName, fallback) == 0) {
- for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) {
- if (GetFamilyOrAliasNum(fallback, &faceNum)) {
- goto found;
- }
- }
- }
- break;
- }
+ while (aliases && !nsFont) {
+ nsFont = FindNSFont(*aliases++, traits, weight, points, 0);
}
}
-
-found:
- style = 0;
- if (faPtr->weight != TK_FW_NORMAL) {
- style |= bold;
- }
- if (faPtr->slant != TK_FS_ROMAN) {
- style |= italic;
+ if (!nsFont) {
+ nsFont = FindNSFont(faPtr->family, traits, weight, points, 1);
}
- if (faPtr->underline) {
- style |= underline;
+ if (!nsFont) {
+ Tcl_Panic("Could not deternmine NSFont from TkFontAttributes");
}
if (tkFontPtr == NULL) {
fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
} else {
fontPtr = (MacFont *) tkFontPtr;
- ReleaseFont(fontPtr);
+ TkpDeleteFont(tkFontPtr);
}
- InitFont(tkwin, faceNum, NULL, faPtr->size, style, fontPtr);
+ CFRetain(nsFont); /* Always needed to allow unconditional CFRelease below */
+ InitFont(nsFont, faPtr, fontPtr);
return (TkFont *) fontPtr;
}
@@ -597,7 +555,10 @@ void
TkpDeleteFont(
TkFont *tkFontPtr) /* Token of font to be deleted. */
{
- ReleaseFont((MacFont *) tkFontPtr);
+ MacFont *fontPtr = (MacFont *) tkFontPtr;
+
+ TkMacOSXMakeCollectableAndRelease(fontPtr->nsAttributes);
+ CFRelease(fontPtr->nsFont); /* Either a CTFontRef or a CFRetained NSFont */
}
/*
@@ -623,14 +584,14 @@ TkpGetFontFamilies(
Tcl_Interp *interp, /* Interp to hold result. */
Tk_Window tkwin) /* For display to query. */
{
- FontNameMap *mapPtr;
- Tcl_Obj *resultPtr, *strPtr;
+ Tcl_Obj *resultPtr = Tcl_NewListObj(0, NULL);
+ NSArray *list = [[NSFontManager sharedFontManager] availableFontFamilies];
- resultPtr = Tcl_GetObjResult(interp);
- for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) {
- strPtr = Tcl_NewStringObj(mapPtr->utfName, -1);
- Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
+ for (NSString *family in list) {
+ Tcl_ListObjAppendElement(NULL, resultPtr,
+ Tcl_NewStringObj([family UTF8String], -1));
}
+ Tcl_SetObjResult(interp, resultPtr);
}
/*
@@ -656,210 +617,138 @@ TkpGetSubFonts(
Tcl_Interp *interp, /* Interp to hold result. */
Tk_Font tkfont) /* Font object to query. */
{
- int i;
- Tcl_Obj *resultPtr, *strPtr;
- MacFont *fontPtr;
- FontFamily *familyPtr;
- Str255 nativeName;
+ MacFont *fontPtr = (MacFont *) tkfont;
+ Tcl_Obj *resultPtr = Tcl_NewListObj(0, NULL);
+
+ if (fontPtr->nsFont) {
+ NSArray *list = [[fontPtr->nsFont fontDescriptor]
+ objectForKey:NSFontCascadeListAttribute];
+
+ for (NSFontDescriptor *subFontDesc in list) {
+ NSString *family = [subFontDesc objectForKey:NSFontFamilyAttribute];
+
+ if (family) {
+ Tcl_ListObjAppendElement(NULL, resultPtr,
+ Tcl_NewStringObj([family UTF8String], -1));
+ }
+ }
+ }
+ Tcl_SetObjResult(interp, resultPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetFontAttrsForChar --
+ *
+ * Retrieve the font attributes of the actual font used to render a
+ * given character.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The font attributes are stored in *faPtr.
+ *
+ *----------------------------------------------------------------------
+ */
- resultPtr = Tcl_GetObjResult(interp);
- fontPtr = (MacFont *) tkfont;
- for (i = 0; i < fontPtr->numSubFonts; i++) {
- familyPtr = fontPtr->subFontArray[i].familyPtr;
- GetFontName(familyPtr->faceNum, nativeName);
- strPtr = Tcl_NewStringObj(GetUtfFaceName(nativeName), -1);
- Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
+void
+TkpGetFontAttrsForChar(
+ Tk_Window tkwin, /* Window on the font's display */
+ Tk_Font tkfont, /* Font to query */
+ Tcl_UniChar c, /* Character of interest */
+ TkFontAttributes* faPtr) /* Output: Font attributes */
+{
+ MacFont *fontPtr = (MacFont *) tkfont;
+ NSFont *nsFont = fontPtr->nsFont;
+
+ *faPtr = fontPtr->font.fa;
+ if (nsFont && ![[nsFont coveredCharacterSet] characterIsMember:c]) {
+ UTF16Char ch = c;
+
+ nsFont = [nsFont bestMatchingFontForCharacters:&ch
+ length:1 attributes:nil actualCoveredLength:NULL];
+ if (nsFont) {
+ GetTkFontAttributesForNSFont(nsFont, faPtr);
+ }
}
}
+
+#pragma mark -
+#pragma mark Measuring and drawing:
/*
*---------------------------------------------------------------------------
*
- * Tk_MeasureChars --
+ * Tk_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.
+ * 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.
+ *
+ * With ATSUI we need the line context to do this right, so we have the
+ * actual implementation in TkpMeasureCharsInContext().
*
* Results:
- * The return value is the number of bytes from source that
- * fit into the span that extends from 0 to maxLength. *lengthPtr is
- * filled with the x-coordinate of the right edge of the last
- * character that did fit.
+ * The return value is the number of bytes from source that fit into the
+ * span that extends from 0 to maxLength. *lengthPtr is filled with the
+ * x-coordinate of the right edge of the last character that did fit.
*
* Side effects:
* None.
*
+ * Todo:
+ * Effects of the "flags" parameter are untested.
+ *
*---------------------------------------------------------------------------
*/
int
Tk_MeasureChars(
Tk_Font tkfont, /* Font in which characters will be drawn. */
- CONST char *source, /* UTF-8 string to be displayed. Need not be
+ const char *source, /* UTF-8 string to be displayed. Need not be
* '\0' terminated. */
- int numBytes, /* Maximum number of bytes to consider
- * from source string. */
+ int 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
- * character that would cross this
- * x-position. If < 0, then line length is
- * unbounded and the flags argument is
- * ignored. */
+ * character that would cross this x-position.
+ * If < 0, then line length is unbounded and
+ * the flags argument is ignored. */
int flags, /* Various flag bits OR-ed together:
* TK_PARTIAL_OK means include the last char
* which only partially fit on this line.
* TK_WHOLE_WORDS means stop on a word
- * boundary, if possible.
- * TK_AT_LEAST_ONE means return at least one
- * character even if no characters fit. */
+ * boundary, if possible. TK_AT_LEAST_ONE
+ * means return at least one character even if
+ * no characters fit. */
int *lengthPtr) /* Filled with x-location just after the
* terminating character. */
{
- MacFont *fontPtr;
- SubFont *thisSubFontPtr, *lastSubFontPtr;
- CGrafPtr savePort;
- Boolean portChanged;
- int curX, curByte;
-
- /*
- * According to "Inside Macintosh: Text", the Macintosh may
- * automatically substitute
- * ligatures or context-sensitive presentation forms when
- * measuring/displaying text within a font run. We cannot safely
- * measure individual characters and add up the widths w/o errors.
- * However, if we convert a range of text from UTF-8 to, say,
- * Shift-JIS, and get the offset into the Shift-JIS string as to
- * where a word or line break would occur, then can we map that
- * number back to UTF-8?
- */
-
- fontPtr = (MacFont *) tkfont;
-
- portChanged = QDSwapPort(gWorld, &savePort);
-
- TextSize(fontPtr->size);
- TextFace(fontPtr->style);
-
- lastSubFontPtr = &fontPtr->subFontArray[0];
-
- if (numBytes == 0) {
- curX = 0;
- curByte = 0;
- } else if (maxLength < 0) {
- const char *p, *end, *next;
- Tcl_UniChar ch;
- 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;
- TextFont(familyPtr->faceNum);
- Tcl_UtfToExternalDString(familyPtr->encoding, source,
- p - source, &runString);
- curX += TextWidth(Tcl_DStringValue(&runString), 0,
- Tcl_DStringLength(&runString));
- Tcl_DStringFree(&runString);
- lastSubFontPtr = thisSubFontPtr;
- source = p;
- }
- p = next;
- }
- familyPtr = lastSubFontPtr->familyPtr;
- TextFont(familyPtr->faceNum);
- Tcl_UtfToExternalDString(familyPtr->encoding, source, p - source,
- &runString);
- curX += TextWidth(Tcl_DStringValue(&runString), 0,
- Tcl_DStringLength(&runString));
- Tcl_DStringFree(&runString);
- curByte = numBytes;
- } else {
- const char *p, *end, *next, *sourceOrig;
- int widthLeft;
- Tcl_UniChar ch;
- const char *rest = NULL;
-
- /*
- * How many chars will fit in the space allotted?
- */
-
- if (maxLength > 32767) {
- maxLength = 32767;
- }
-
- widthLeft = maxLength;
- sourceOrig = source;
- end = source + numBytes;
- for (p = source; p < end; p = next) {
- next = p + Tcl_UtfToUniChar(p, &ch);
- thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
- if (thisSubFontPtr != lastSubFontPtr) {
- if (p > source) {
- rest = BreakLine(lastSubFontPtr->familyPtr, flags, source,
- p - source, &widthLeft);
- flags &= ~TK_AT_LEAST_ONE;
- if (rest != NULL) {
- p = source;
- break;
- }
- }
- lastSubFontPtr = thisSubFontPtr;
- source = p;
- }
- }
-
- if (p > source) {
- rest = BreakLine(lastSubFontPtr->familyPtr, flags, source, p - source,
- &widthLeft);
- }
-
- if (rest == NULL) {
- curByte = numBytes;
- } else {
- curByte = rest - sourceOrig;
- }
- curX = maxLength - widthLeft;
- }
-
- if (portChanged) {
- QDSwapPort(savePort, NULL);
- }
-
- *lengthPtr = curX;
- return curByte;
+ return TkpMeasureCharsInContext(tkfont, source, numBytes, 0, numBytes,
+ maxLength, flags, lengthPtr);
}
/*
*---------------------------------------------------------------------------
*
- * BreakLine --
+ * TkpMeasureCharsInContext --
+ *
+ * Determine the number of bytes from the string that will fit in the
+ * given horizontal span. The measurement is done under the assumption
+ * that TkpDrawCharsInContext() will be used to actually display the
+ * characters.
*
- * Determine where the given line of text should be broken so that it
- * fits in the specified range. Before calling this function, the
- * font values and graphics port must be set.
+ * This one is almost the same as Tk_MeasureChars(), but with access to
+ * all the characters on the line for context.
*
* Results:
- * The return value is NULL if the specified range is larger that the
- * space the text needs, and *widthLeftPtr is filled with how much
- * space is left in the range after measuring the whole text buffer.
- * Otherwise, the return value is a pointer into the text buffer that
- * indicates where the line should be broken (up to, but not including
- * that character), and *widthLeftPtr is filled with how much space is
- * left in the range after measuring up to that character.
+ * The return value is the number of bytes from source that
+ * fit into the span that extends from 0 to maxLength. *lengthPtr is
+ * filled with the x-coordinate of the right edge of the last
+ * character that did fit.
*
* Side effects:
* None.
@@ -867,122 +756,160 @@ Tk_MeasureChars(
*---------------------------------------------------------------------------
*/
-static const char *
-BreakLine(
- FontFamily *familyPtr, /* FontFamily that describes the font values
- * that are already selected into the graphics
- * port. */
+int
+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
+ * source string in all. */
+ int rangeStart, /* Index of first byte to measure. */
+ int 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.
+ * If < 0, then line length is unbounded and
+ * the flags argument is ignored. */
int flags, /* Various flag bits OR-ed together:
* TK_PARTIAL_OK means include the last char
- * which only partially fit on this line.
+ * which only partially fits on this line.
* TK_WHOLE_WORDS means stop on a word
- * boundary, if possible.
- * TK_AT_LEAST_ONE means return at least one
- * character even if no characters fit. */
- const char *source, /* UTF-8 string to be displayed. Need not be
- * '\0' terminated. */
- int numBytes, /* Maximum number of bytes to consider
- * from source string. */
- int *widthLeftPtr) /* On input, specifies size of range into
- * which characters from source buffer should
- * be fit. On output, filled with how much
- * space is left after fitting as many
- * characters as possible into the range.
- * Result may be negative if TK_AT_LEAST_ONE
- * was specified in the flags argument. */
+ * boundary, if possible. TK_AT_LEAST_ONE
+ * means return at least one character even
+ * if no characters fit. If TK_WHOLE_WORDS
+ * and TK_AT_LEAST_ONE are set and the first
+ * word doesn't fit, we return at least one
+ * character or whatever characters fit into
+ * maxLength. TK_ISOLATE_END means that the
+ * last character should not be considered in
+ * context with the rest of the string (used
+ * for breaking lines). */
+ int *lengthPtr) /* Filled with x-location just after the
+ * terminating character. */
{
- Fixed pixelWidth, widthLeft;
- StyledLineBreakCode breakCode;
- Tcl_DString runString;
- long textOffset;
- Boolean leadingEdge;
- Point point;
- int charOffset, thisCharWasDoubleByte;
- char *p, *end, *typeTable;
-
- TextFont(familyPtr->faceNum);
- Tcl_UtfToExternalDString(familyPtr->encoding, source, numBytes,
- &runString);
- pixelWidth = IntToFixed(*widthLeftPtr) + 1;
- if (flags & TK_WHOLE_WORDS) {
- textOffset = (flags & TK_AT_LEAST_ONE);
- widthLeft = pixelWidth;
- breakCode = StyledLineBreak(Tcl_DStringValue(&runString),
- Tcl_DStringLength(&runString), 0, Tcl_DStringLength(&runString),
- 0, &widthLeft, &textOffset);
- if (breakCode != smBreakOverflow) {
- /*
- * StyledLineBreak includes all the space characters at the end of
- * line that we want to suppress.
- */
-
- textOffset = VisibleLength(Tcl_DStringValue(&runString), textOffset);
- goto getoffset;
- }
- } else {
- point.v = 1;
- point.h = 1;
- textOffset = PixelToChar(Tcl_DStringValue(&runString),
- Tcl_DStringLength(&runString), 0, pixelWidth, &leadingEdge,
- &widthLeft, smOnlyStyleRun, point, point);
- if (FixedToInt(widthLeft) < 0) {
- goto getoffset;
- }
+ const MacFont *fontPtr = (const MacFont *) tkfont;
+ NSString *string;
+ NSAttributedString *attributedString;
+ CTTypesetterRef typesetter;
+ CFIndex start, len;
+ CFRange range = {0, 0};
+ CTLineRef line;
+ CGFloat offset = 0;
+ CFIndex index;
+ double width;
+ int length, fit;
+
+ if (rangeStart < 0 || rangeLength <= 0 ||
+ rangeStart + rangeLength > numBytes ||
+ (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) {
+ *lengthPtr = 0;
+ return 0;
}
- *widthLeftPtr = FixedToInt(widthLeft);
- Tcl_DStringFree(&runString);
- return NULL;
-
- /*
- * The conversion routine that converts UTF-8 to the target encoding
- * must map one UTF-8 character to exactly one encoding-specific
- * character, so that the following algorithm works:
- *
- * 1. Get byte offset of where line should be broken.
- * 2. Get char offset corresponding to that byte offset.
- * 3. Map that char offset to byte offset in UTF-8 string.
- */
-
- getoffset:
- thisCharWasDoubleByte = 0;
- if (familyPtr->isMultiByteFont == 0) {
- charOffset = textOffset;
+#if 0
+ /* Back-compatibility with ATSUI renderer, appears not to be needed */
+ if (rangeStart == 0 && maxLength == 1 && (flags & TK_ISOLATE_END) &&
+ !(flags & TK_AT_LEAST_ONE)) {
+ length = 0;
+ fit = 0;
+ goto done;
+ }
+#endif
+ if (maxLength > 32767) {
+ maxLength = 32767;
+ }
+ string = [[NSString alloc] initWithBytesNoCopy:(void*)source
+ length:numBytes encoding:NSUTF8StringEncoding freeWhenDone:NO];
+ if (!string) {
+ length = 0;
+ fit = rangeLength;
+ goto done;
+ }
+ attributedString = [[NSAttributedString alloc] initWithString:string
+ attributes:fontPtr->nsAttributes];
+ typesetter = CTTypesetterCreateWithAttributedString(
+ (CFAttributedStringRef)attributedString);
+ start = Tcl_NumUtfChars(source, rangeStart);
+ len = Tcl_NumUtfChars(source + rangeStart, rangeLength);
+ if (start > 0) {
+ range.length = start;
+ line = CTTypesetterCreateLine(typesetter, range);
+ offset = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
+ CFRelease(line);
+ }
+ if (maxLength < 0) {
+ index = len;
+ range.length = len;
+ line = CTTypesetterCreateLine(typesetter, range);
+ width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
+ CFRelease(line);
} else {
- charOffset = 0;
- typeTable = familyPtr->typeTable;
-
- p = Tcl_DStringValue(&runString);
- end = p + textOffset;
- thisCharWasDoubleByte = typeTable[*((unsigned char *) p)];
- for ( ; p < end; p++) {
- thisCharWasDoubleByte = typeTable[*((unsigned char *) p)];
- p += thisCharWasDoubleByte;
- charOffset++;
+ double maxWidth = maxLength + offset;
+ NSCharacterSet *cs;
+
+ index = start;
+ if (flags & TK_WHOLE_WORDS) {
+ index = CTTypesetterSuggestLineBreak(typesetter, start, maxWidth);
+ if (index <= start && (flags & TK_AT_LEAST_ONE)) {
+ flags &= ~TK_WHOLE_WORDS;
+ }
+ }
+ if (index <= start && !(flags & TK_WHOLE_WORDS)) {
+ index = CTTypesetterSuggestClusterBreak(typesetter, start, maxWidth);
+ }
+ cs = (index < len || (flags & TK_WHOLE_WORDS)) ?
+ whitespaceCharacterSet : lineendingCharacterSet;
+ while (index > start &&
+ [cs characterIsMember:[string characterAtIndex:(index - 1)]]) {
+ index--;
+ }
+ if (index <= start && (flags & TK_AT_LEAST_ONE)) {
+ index = start + 1;
+ }
+ if (index > 0) {
+ range.length = index;
+ line = CTTypesetterCreateLine(typesetter, range);
+ width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
+ CFRelease(line);
+ } else {
+ width = 0;
+ }
+ if (width < maxWidth && (flags & TK_PARTIAL_OK) && index < len) {
+ range.length = ++index;
+ line = CTTypesetterCreateLine(typesetter, range);
+ width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
+ CFRelease(line);
}
- }
- if ((flags & TK_WHOLE_WORDS) == 0) {
- if ((flags & TK_PARTIAL_OK) && (leadingEdge != 0)) {
- textOffset += thisCharWasDoubleByte;
- textOffset++;
- charOffset++;
- } else if (((flags & TK_PARTIAL_OK) == 0) && (leadingEdge == 0)) {
- textOffset -= thisCharWasDoubleByte;
- textOffset--;
- charOffset--;
+ /* The call to CTTypesetterSuggestClusterBreak above will always
+ return at least one character regardless of whether it exceeded
+ it or not. Clean that up now. */
+ while (width > maxWidth && !(flags & TK_PARTIAL_OK) && index > start+(flags & TK_AT_LEAST_ONE)) {
+ range.length = --index;
+ line = CTTypesetterCreateLine(typesetter, range);
+ width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
+ CFRelease(line);
}
+
}
- if ((textOffset == 0) && (Tcl_DStringLength(&runString) > 0)
- && (flags & TK_AT_LEAST_ONE)) {
- p = Tcl_DStringValue(&runString);
- textOffset += familyPtr->typeTable[*((unsigned char *) p)];
- textOffset++;
- charOffset++;
- }
- *widthLeftPtr = FixedToInt(pixelWidth)
- - TextWidth(Tcl_DStringValue(&runString), 0, textOffset);
- Tcl_DStringFree(&runString);
- return Tcl_UtfAtIndex(source, charOffset);
+ CFRelease(typesetter);
+ [attributedString release];
+ [string release];
+ length = ceil(width - offset);
+ fit = (Tcl_UtfAtIndex(source, index) - source) - rangeStart;
+done:
+#ifdef TK_MAC_DEBUG_FONTS
+ TkMacOSXDbgMsg("measure: source=\"%s\" range=\"%.*s\" maxLength=%d "
+ "flags='%s%s%s%s' -> width=%d bytesFit=%d\n", source, rangeLength,
+ source+rangeStart, maxLength,
+ flags & TK_PARTIAL_OK ? "partialOk " : "",
+ flags & TK_WHOLE_WORDS ? "wholeWords " : "",
+ flags & TK_AT_LEAST_ONE ? "atLeastOne " : "",
+ flags & TK_ISOLATE_END ? "isolateEnd " : "",
+ length, fit);
+//if (!(rangeLength==1 && rangeStart == 0)) fprintf(stderr, " measure len=%d (max=%d, w=%.0f) from %d (nb=%d): source=\"%s\": index=%d return %d\n",rangeLength,maxLength,width,rangeStart,numBytes, source+rangeStart, index, fit);
+#endif
+ *lengthPtr = length;
+ return fit;
}
/*
@@ -992,8 +919,11 @@ BreakLine(
*
* Draw a string of characters on the screen.
*
+ * With ATSUI we need the line context to do this right, so we have the
+ * actual implementation in TkpDrawCharsInContext().
+ *
* Results:
- * None.
+ * None.
*
* Side effects:
* Information gets drawn on the screen.
@@ -1008,7 +938,7 @@ Tk_DrawChars(
GC gc, /* Graphics context for drawing characters. */
Tk_Font tkfont, /* Font in which characters will be drawn; must
* be the same as font used in GC. */
- CONST char *source, /* UTF-8 string to be displayed. Need not be
+ const char *source, /* UTF-8 string to be displayed. Need not be
* '\0' terminated. All Tk meta-characters
* (tabs, control characters, and newlines)
* should be stripped out of the string that
@@ -1019,837 +949,181 @@ Tk_DrawChars(
int x, int y) /* Coordinates at which to place origin of the
* string when drawing. */
{
- MacDrawable *macWin = (MacDrawable *) drawable;
- MacFont *fontPtr = (MacFont *) tkfont;
- TkMacOSXDrawingContext drawingContext;
-
- if (!TkMacOSXSetupDrawingContext(drawable, gc, 0, &drawingContext)) {
- return;
- }
-#if 0
- /*
- * Stippled QD text drawing only kind of works and is ugly, so disable it
- * for now:
- */
- if ((gc->fill_style == FillStippled
- || gc->fill_style == FillOpaqueStippled)
- && gc->stipple != None) {
- TkMacOSXDrawingContext pixmapDrawingContext;
- BitMapPtr stippleMap;
- Pixmap pixmap;
- Pattern white;
- Rect bounds = drawingContext.portBounds;
-
- OffsetRect(&bounds, macWin->xOff + x, 0);
- stippleMap = TkMacOSXMakeStippleMap(drawable, gc->stipple);
- pixmap = Tk_GetPixmap(display, drawable,
- stippleMap->bounds.right, stippleMap->bounds.bottom, 0);
- if (!TkMacOSXSetupDrawingContext(pixmap, gc, 0,
- &pixmapDrawingContext)) {
- return;
- }
- GetQDGlobalsWhite(&white);
- FillRect(&stippleMap->bounds, &white);
- MultiFontDrawText(fontPtr, source, numBytes, 0, macWin->yOff + y);
- TkMacOSXRestoreDrawingContext(&pixmapDrawingContext);
- CopyDeepMask(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort(pixmap)),
- stippleMap, GetPortBitMapForCopyBits(
- TkMacOSXGetDrawablePort(drawable)), &stippleMap->bounds,
- &stippleMap->bounds, &bounds, srcOr, NULL);
-
- /* TODO: this doesn't work quite right - it does a blend. You can't
- * draw white text when you have a stipple.
- */
-
- Tk_FreePixmap(display, pixmap);
- ckfree(stippleMap->baseAddr);
- ckfree((char *)stippleMap);
- } else
-#endif
- {
- MultiFontDrawText(fontPtr, source, numBytes, macWin->xOff + x,
- macWin->yOff + y);
- }
- TkMacOSXRestoreDrawingContext(&drawingContext);
-}
-
-/*
- *-------------------------------------------------------------------------
- *
- * MultiFontDrawText --
- *
- * Helper function for Tk_DrawChars. Draws characters, using the
- * various screen fonts in fontPtr to draw multilingual characters.
- * Note: No bidirectional support.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Information gets drawn on the screen.
- * Contents of fontPtr may be modified if more subfonts were loaded
- * in order to draw all the multilingual characters in the given
- * string.
- *
- *-------------------------------------------------------------------------
- */
-
-static void
-MultiFontDrawText(
- MacFont *fontPtr, /* Contains set of fonts to use when drawing
- * following string. */
- const char *source, /* Potentially multilingual UTF-8 string. */
- int numBytes, /* Length of string in bytes. */
- int x, int y) /* Coordinates at which to place origin *
- * of string when drawing. */
-{
- SubFont *thisSubFontPtr, *lastSubFontPtr;
- FontFamily *familyPtr;
- Tcl_DString runString;
- const char *p, *end, *next;
- Tcl_UniChar ch;
-
- TextSize(fontPtr->size);
- TextFace(fontPtr->style);
-
- lastSubFontPtr = &fontPtr->subFontArray[0];
-
- end = source + numBytes;
- for (p = source; p < end; ) {
- next = p + Tcl_UtfToUniChar(p, &ch);
- thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
- if (thisSubFontPtr != lastSubFontPtr) {
- if (p > source) {
- familyPtr = lastSubFontPtr->familyPtr;
- TextFont(familyPtr->faceNum);
- Tcl_UtfToExternalDString(familyPtr->encoding, source,
- p - source, &runString);
- MoveTo((short) x, (short) y);
- DrawText(Tcl_DStringValue(&runString), 0,
- Tcl_DStringLength(&runString));
- x += TextWidth(Tcl_DStringValue(&runString), 0,
- Tcl_DStringLength(&runString));
- Tcl_DStringFree(&runString);
- source = p;
- }
- lastSubFontPtr = thisSubFontPtr;
- }
- p = next;
- }
- if (p > source) {
- familyPtr = lastSubFontPtr->familyPtr;
- TextFont(familyPtr->faceNum);
- Tcl_UtfToExternalDString(familyPtr->encoding, source,
- p - source, &runString);
- MoveTo((short) x, (short) y);
- DrawText(Tcl_DStringValue(&runString), 0,
- Tcl_DStringLength(&runString));
- Tcl_DStringFree(&runString);
- }
+ DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
+ 0, numBytes, x, y, 0.0);
}
/*
*---------------------------------------------------------------------------
*
- * TkMacOSXIsCharacterMissing --
+ * TkpDrawCharsInContext --
*
- * Given a tkFont and a character determines whether the character has
- * a glyph defined in the font or not. Note that this is potentially
- * not compatible with Mac OS 8 as it looks at the font handle
- * structure directly. Looks into the character array of the font
- * handle to determine whether the glyph is defined or not.
+ * Draw a string of characters on the screen like Tk_DrawChars(), with
+ * access to all the characters on the line for context.
*
* Results:
- * Returns a 1 if the character is missing, a 0 if it is not.
- *
- * Side effects:
* None.
*
- *---------------------------------------------------------------------------
- */
-
-int
-TkMacOSXIsCharacterMissing(
- Tk_Font tkfont, /* The font we are looking in. */
- unsigned int searchChar) /* The character we are looking for. */
-{
- /*
- * For some reason, FMSwapFont always returns a NULL font handle under OS X
- * Until we figure this one out, return 0;
- */
-
- return 0;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * InitFont --
- *
- * Helper for TkpGetNativeFont() and TkpGetFontFromAttributes().
- * Initializes the memory for a MacFont that wraps the platform-specific
- * data.
- *
- * The caller is responsible for initializing the fields of the
- * TkFont that are used exclusively by the generic TkFont code, and
- * for releasing those fields before calling TkpDeleteFont().
- *
- * Results:
- * Fills the MacFont structure.
- *
* Side effects:
- * Memory allocated.
- *
- *---------------------------------------------------------------------------
- */
-
-static void
-InitFont(
- Tk_Window tkwin, /* For display where font will be used. */
- int faceNum, /* Macintosh font number. */
- unsigned char *familyName, /* The font family name or NULL. */
- int size, /* Point size for Macintosh font. */
- int style, /* Macintosh style bits. */
- MacFont *fontPtr) /* Filled with information constructed from
- * the above arguments. */
-{
- Str255 nativeName;
- FontInfo fi;
- TkFontAttributes *faPtr;
- TkFontMetrics *fmPtr;
- CGrafPtr savePort;
- Boolean portChanged;
- short pixels;
-
- if (size == 0) {
- size = -GetDefFontSize();
- }
- pixels = (short) TkFontGetPixels(tkwin, size);
-
- portChanged = QDSwapPort(gWorld, &savePort);
- TextFont(faceNum);
- TextSize(pixels);
- TextFace(style);
-
- GetFontInfo(&fi);
- if (!familyName) {
- GetFontName(faceNum, nativeName);
- familyName = nativeName;
- }
- fontPtr->font.fid = (Font) fontPtr;
-
- faPtr = &fontPtr->font.fa;
- faPtr->family = GetUtfFaceName(familyName);
- faPtr->size = TkFontGetPoints(tkwin, size);
- faPtr->weight = (style & bold) ? TK_FW_BOLD : TK_FW_NORMAL;
- faPtr->slant = (style & italic) ? TK_FS_ITALIC : TK_FS_ROMAN;
- faPtr->underline = ((style & underline) != 0);
- faPtr->overstrike = 0;
-
- fmPtr = &fontPtr->font.fm;
- fmPtr->ascent = fi.ascent;
- fmPtr->descent = fi.descent;
- fmPtr->maxWidth = fi.widMax;
- fmPtr->fixed = (CharWidth('i') == CharWidth('w'));
-
- fontPtr->size = pixels;
- fontPtr->style = (short) style;
-
- fontPtr->numSubFonts = 1;
- fontPtr->subFontArray = fontPtr->staticSubFonts;
- InitSubFont(fontPtr, faceNum, &fontPtr->subFontArray[0]);
-
- if (portChanged) {
- QDSwapPort(savePort, NULL);
- }
-}
-
-/*
- *-------------------------------------------------------------------------
- *
- * ReleaseFont --
- *
- * Called to release the Macintosh-specific contents of a TkFont.
- * The caller is responsible for freeing the memory used by the
- * font itself.
- *
- * Results:
- * None.
+ * Information gets drawn on the screen.
*
- * Side effects:
- * Memory is freed.
+ * Todo:
+ * Stippled text drawing.
*
*---------------------------------------------------------------------------
*/
-static void
-ReleaseFont(
- MacFont *fontPtr) /* The font to delete. */
+void
+TkpDrawCharsInContext(
+ Display *display, /* Display on which to draw. */
+ Drawable drawable, /* Window or pixmap in which to draw. */
+ GC gc, /* Graphics context for drawing characters. */
+ Tk_Font tkfont, /* Font in which characters will be drawn; must
+ * be the same as font used in GC. */
+ const char * source, /* UTF-8 string to be displayed. Need not be
+ * '\0' terminated. All Tk meta-characters
+ * (tabs, control characters, and newlines)
+ * should be stripped out of the string that
+ * is 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. */
+ int x, int y) /* Coordinates at which to place origin of the
+ * whole (not just the range) string when
+ * drawing. */
{
- int i;
-
- for (i = 0; i < fontPtr->numSubFonts; i++) {
- ReleaseSubFont(&fontPtr->subFontArray[i]);
- }
- if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
- ckfree((char *) fontPtr->subFontArray);
- }
+ DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
+ rangeStart, rangeLength, x, y, 0.0);
}
-/*
- *-------------------------------------------------------------------------
- *
- * InitSubFont --
- *
- * Wrap a screen font and load the FontFamily that represents
- * it. Used to prepare a SubFont so that characters can be mapped
- * from UTF-8 to the charset of the font.
- *
- * Results:
- * The subFontPtr is filled with information about the font.
- *
- * Side effects:
- * None.
- *
- *-------------------------------------------------------------------------
- */
-
static void
-InitSubFont(
- const MacFont *fontPtr, /* Font object in which the SubFont will be
- * used. */
- int faceNum, /* The font number. */
- SubFont *subFontPtr) /* Filled with SubFont constructed from
- * above attributes. */
-{
- subFontPtr->familyPtr = AllocFontFamily(fontPtr, faceNum);
- subFontPtr->fontMap = subFontPtr->familyPtr->fontMap;
-}
-
-/*
- *-------------------------------------------------------------------------
- *
- * ReleaseSubFont --
- *
- * Called to release the contents of a SubFont. The caller is
- * responsible for freeing the memory used by the SubFont itself.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Memory and resources are freed.
- *
- *---------------------------------------------------------------------------
- */
-
-static void
-ReleaseSubFont(
- SubFont *subFontPtr) /* The SubFont to delete. */
-{
- FreeFontFamily(subFontPtr->familyPtr);
-}
-
-/*
- *-------------------------------------------------------------------------
- *
- * AllocFontFamily --
- *
- * Find the FontFamily structure associated with the given font
- * family. The information should be stored by the caller in a
- * SubFont and used when determining if that SubFont supports a
- * character.
- *
- * Results:
- * A pointer to a FontFamily. The reference count in the FontFamily
- * is automatically incremented. When the SubFont is released, the
- * reference count is decremented. When no SubFont is using this
- * FontFamily, it may be deleted.
- *
- * Side effects:
- * A new FontFamily structure will be allocated if this font family
- * has not been seen.
- *
- *-------------------------------------------------------------------------
- */
-
-static FontFamily *
-AllocFontFamily(
- const MacFont *fontPtr, /* Font object in which the FontFamily will
- * be used. */
- int faceNum) /* The font number. */
-{
- FontFamily *familyPtr;
- int i;
-
- familyPtr = fontFamilyList;
- for (; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
- if (familyPtr->faceNum == faceNum) {
- familyPtr->refCount++;
- return familyPtr;
- }
- }
-
- familyPtr = (FontFamily *) ckalloc(sizeof(FontFamily));
- memset(familyPtr, 0, sizeof(FontFamily));
- familyPtr->nextPtr = fontFamilyList;
- fontFamilyList = familyPtr;
-
- /*
- * Set key for this FontFamily.
- */
-
- familyPtr->faceNum = faceNum;
-
- /*
- * An initial refCount of 2 means that FontFamily information will
- * persist even when the SubFont that loaded the FontFamily is released.
- * Change it to 1 to cause FontFamilies to be unloaded when not in use.
- */
-
- familyPtr->refCount = 2;
- familyPtr->encoding = GetFontEncoding(faceNum, 1, &familyPtr->isSymbolFont);
- familyPtr->isMultiByteFont = 0;
- FillParseTable(familyPtr->typeTable, FontToScript(faceNum));
- for (i = 0; i < 256; i++) {
- if (familyPtr->typeTable[i] != 0) {
- familyPtr->isMultiByteFont = 1;
- break;
- }
- }
- return familyPtr;
-}
-
-/*
- *-------------------------------------------------------------------------
- *
- * FreeFontFamily --
- *
- * Called to free a FontFamily when the SubFont is finished using it.
- * Frees the contents of the FontFamily and the memory used by the
- * FontFamily itself.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-------------------------------------------------------------------------
- */
-
-static void
-FreeFontFamily(
- FontFamily *familyPtr) /* The FontFamily to delete. */
+DrawCharsInContext(
+ Display *display, /* Display on which to draw. */
+ Drawable drawable, /* Window or pixmap in which to draw. */
+ GC gc, /* Graphics context for drawing characters. */
+ Tk_Font tkfont, /* Font in which characters will be drawn; must
+ * be the same as font used in GC. */
+ const char * source, /* UTF-8 string to be displayed. Need not be
+ * '\0' terminated. All Tk meta-characters
+ * (tabs, control characters, and newlines)
+ * should be stripped out of the string that
+ * is 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. */
+ int x, int y, /* Coordinates at which to place origin of the
+ * whole (not just the range) string when
+ * drawing. */
+ double angle)
{
- FontFamily **familyPtrPtr;
- int i;
-
- if (familyPtr == NULL) {
+ const MacFont *fontPtr = (const MacFont *) tkfont;
+ NSString *string;
+ NSMutableDictionary *attributes;
+ NSAttributedString *attributedString;
+ CTTypesetterRef typesetter;
+ CFIndex start, len;
+ CTLineRef line;
+ MacDrawable *macWin = (MacDrawable *) drawable;
+ TkMacOSXDrawingContext drawingContext;
+ CGContextRef context;
+ CGColorRef fg;
+ NSFont *nsFont;
+ CGAffineTransform t;
+ int h;
+
+ if (rangeStart < 0 || rangeLength <= 0 ||
+ rangeStart + rangeLength > numBytes ||
+ !TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) {
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((char *) familyPtr->fontMap[i]);
- }
- }
-
- /*
- * Delete from list.
- */
-
- for (familyPtrPtr = &fontFamilyList; ; ) {
- if (*familyPtrPtr == familyPtr) {
- *familyPtrPtr = familyPtr->nextPtr;
- break;
- }
- familyPtrPtr = &(*familyPtrPtr)->nextPtr;
- }
-
- ckfree((char *) familyPtr);
-}
-
-/*
- *-------------------------------------------------------------------------
- *
- * FindSubFontForChar --
- *
- * Determine which physical screen font is necessary to use to
- * display the given character. If the font object does not have
- * a screen font that can display the character, another screen font
- * may be loaded into the font object, following a set of preferred
- * fallback rules.
- *
- * Results:
- * The return value is the SubFont to use to display the given
- * character.
- *
- * Side effects:
- * The contents of fontPtr are modified to cache the results
- * of the lookup and remember any SubFonts that were dynamically
- * loaded. The table of SubFonts might be extended, and if a non-NULL
- * reference to a subfont pointer is available, it is updated if it
- * previously pointed into the old subfont table.
- *
- *-------------------------------------------------------------------------
- */
-
-static SubFont *
-FindSubFontForChar(
- MacFont *fontPtr, /* The font object with which the character
- * will be displayed. */
- int ch, /* The Unicode character to be displayed. */
- SubFont **fixSubFontPtrPtr) /* Subfont reference to fix up if we
- * reallocate our subfont table. */
-{
- int i, j, k;
- const char *fallbackName;
- char **aliases;
- SubFont *subFontPtr;
- FontNameMap *mapPtr;
- Tcl_DString faceNames;
- char ***fontFallbacks;
- char **anyFallbacks;
-
- if (FontMapLookup(&fontPtr->subFontArray[0], ch)) {
- return &fontPtr->subFontArray[0];
- }
-
- for (i = 1; i < fontPtr->numSubFonts; i++) {
- if (FontMapLookup(&fontPtr->subFontArray[i], ch)) {
- return &fontPtr->subFontArray[i];
- }
- }
-
- /*
- * Keep track of all face names that we check, so we don't check some
- * name multiple times if it can be reached by multiple paths.
- */
-
- Tcl_DStringInit(&faceNames);
-
- aliases = TkFontGetAliasList(fontPtr->font.fa.family);
-
- subFontPtr = NULL;
- fontFallbacks = TkFontGetFallbacks();
- for (i = 0; fontFallbacks[i] != NULL; i++) {
- for (j = 0; fontFallbacks[i][j] != NULL; j++) {
- fallbackName = fontFallbacks[i][j];
- if (strcasecmp(fallbackName, fontPtr->font.fa.family) == 0) {
- /*
- * If the base font has a fallback...
- */
-
- goto tryfallbacks;
- } else if (aliases != NULL) {
- /*
- * Or if an alias for the base font has a fallback...
- */
-
- for (k = 0; aliases[k] != NULL; k++) {
- if (strcasecmp(aliases[k], fallbackName) == 0) {
- goto tryfallbacks;
- }
- }
- }
- }
- continue;
-
- /*
- * ...then see if we can use one of the fallbacks, or an
- * alias for one of the fallbacks.
- */
-
- tryfallbacks:
- for (j = 0; fontFallbacks[i][j] != NULL; j++) {
- fallbackName = fontFallbacks[i][j];
- subFontPtr = CanUseFallbackWithAliases(fontPtr, fallbackName,
- ch, &faceNames, fixSubFontPtrPtr);
- if (subFontPtr != NULL) {
- goto end;
- }
- }
- }
-
- /*
- * See if we can use something from the global fallback list.
- */
-
- anyFallbacks = TkFontGetGlobalClass();
- for (i = 0; anyFallbacks[i] != NULL; i++) {
- fallbackName = anyFallbacks[i];
- subFontPtr = CanUseFallbackWithAliases(fontPtr, fallbackName, ch,
- &faceNames, fixSubFontPtrPtr);
- if (subFontPtr != NULL) {
- goto end;
- }
- }
-
- /*
- * Try all face names available in the whole system until we
- * find one that can be used.
- */
-
- for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) {
- fallbackName = mapPtr->utfName;
- if (SeenName(fallbackName, &faceNames) == 0) {
- subFontPtr = CanUseFallback(fontPtr, fallbackName, ch,
- fixSubFontPtrPtr);
- if (subFontPtr != NULL) {
- goto end;
- }
- }
+ string = [[NSString alloc] initWithBytesNoCopy:(void*)source
+ length:numBytes encoding:NSUTF8StringEncoding freeWhenDone:NO];
+ if (!string) {
+ return;
}
-
- end:
- Tcl_DStringFree(&faceNames);
-
- if (subFontPtr == NULL) {
- /*
- * No font can display this character. We will use the base font
- * and have it display the "unknown" character.
- */
-
- subFontPtr = &fontPtr->subFontArray[0];
- FontMapInsert(subFontPtr, ch);
+ context = drawingContext.context;
+ fg = TkMacOSXCreateCGColor(gc, gc->foreground);
+ attributes = [fontPtr->nsAttributes mutableCopy];
+ [attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName];
+ CFRelease(fg);
+ nsFont = [attributes objectForKey:NSFontAttributeName];
+ [nsFont setInContext:[NSGraphicsContext graphicsContextWithGraphicsPort:
+ context flipped:NO]];
+ CGContextSetTextMatrix(context, CGAffineTransformIdentity);
+ attributedString = [[NSAttributedString alloc] initWithString:string
+ attributes:attributes];
+ typesetter = CTTypesetterCreateWithAttributedString(
+ (CFAttributedStringRef)attributedString);
+ x += macWin->xOff;
+ y += macWin->yOff;
+ h = drawingContext.portBounds.size.height;
+ y = h - y;
+ t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, h);
+ if (angle != 0.0) {
+ t = CGAffineTransformTranslate(CGAffineTransformRotate(
+ CGAffineTransformTranslate(t, x, y), angle*M_PI/180.0), -x, -y);
}
- return subFontPtr;
-}
-
-/*
- *-------------------------------------------------------------------------
- *
- * FontMapLookup --
- *
- * See if the screen font can display the given character.
- *
- * Results:
- * The return value is 0 if the screen font cannot display the
- * character, non-zero otherwise.
- *
- * Side effects:
- * New pages are added to the font mapping cache whenever the
- * character belongs to a page that hasn't been seen before.
- * When a page is loaded, information about all the characters on
- * that page is stored, not just for the single character in
- * question.
- *
- *-------------------------------------------------------------------------
- */
-
-static int
-FontMapLookup(
- SubFont *subFontPtr, /* Contains font mapping cache to be queried
- * and possibly updated. */
- int ch) /* Character to be tested. */
-{
- int row, bitOffset;
-
- row = ch >> FONTMAP_SHIFT;
- if (subFontPtr->fontMap[row] == NULL) {
- FontMapLoadPage(subFontPtr, row);
+ CGContextConcatCTM(context, t);
+ CGContextSetTextPosition(context, x, y);
+ start = Tcl_NumUtfChars(source, rangeStart);
+ len = Tcl_NumUtfChars(source, rangeStart + rangeLength);
+ if (start > 0) {
+ CGRect clipRect = CGRectInfinite, startBounds;
+ line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start));
+ startBounds = CTLineGetImageBounds(line, context);
+ CFRelease(line);
+ clipRect.origin.x = startBounds.origin.x + startBounds.size.width;
+ CGContextClipToRect(context, clipRect);
}
- bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
- return (subFontPtr->fontMap[row][bitOffset >> 3] >> (bitOffset & 7)) & 1;
-}
-
-/*
- *-------------------------------------------------------------------------
- *
- * FontMapInsert --
- *
- * Tell the font mapping cache that the given screen font should be
- * used to display the specified character. This is called when no
- * font on the system can be be found that can display that
- * character; we lie to the font and tell it that it can display
- * the character, otherwise we would end up re-searching the entire
- * fallback hierarchy every time that character was seen.
- *
- * Results:
- * None.
- *
- * Side effects:
- * New pages are added to the font mapping cache whenever the
- * character belongs to a page that hasn't been seen before.
- * When a page is loaded, information about all the characters on
- * that page is stored, not just for the single character in
- * question.
- *
- *-------------------------------------------------------------------------
- */
-
-static void
-FontMapInsert(
- SubFont *subFontPtr, /* Contains font mapping cache to be
- * updated. */
- int ch) /* Character to be added to cache. */
-{
- int row, bitOffset;
-
- row = ch >> FONTMAP_SHIFT;
- if (subFontPtr->fontMap[row] == NULL) {
- FontMapLoadPage(subFontPtr, row);
- }
- bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
- subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);
+ line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, len));
+ CTLineDraw(line, context);
+ CFRelease(line);
+ CFRelease(typesetter);
+ [attributedString release];
+ [string release];
+ [attributes release];
+ TkMacOSXRestoreDrawingContext(&drawingContext);
}
-
-/*
- *-------------------------------------------------------------------------
- *
- * FontMapLoadPage --
- *
- * Load information about all the characters on a given page.
- * This information consists of one bit per character that indicates
- * whether the associated HFONT can (1) or cannot (0) display the
- * characters on the page.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Mempry allocated.
- *
- *-------------------------------------------------------------------------
- */
-static void
-FontMapLoadPage(
- SubFont *subFontPtr, /* Contains font mapping cache to be
- * updated. */
- int row) /* Index of the page to be loaded into
- * the cache. */
-{
- FMInput fm;
- FMOutPtr fmOut;
- int i, end, bitOffset, isMultiByteFont;
- char src[TCL_UTF_MAX];
- unsigned char buf[16];
- int srcRead, dstWrote;
- Tcl_Encoding encoding;
- Handle fHandle = NULL;
-
- subFontPtr->fontMap[row] = (char *) ckalloc(FONTMAP_BITSPERPAGE / 8);
- memset(subFontPtr->fontMap[row], 0, FONTMAP_BITSPERPAGE / 8);
-
- encoding = subFontPtr->familyPtr->encoding;
-
- fm.family = subFontPtr->familyPtr->faceNum;
- fm.size = 12;
- fm.face = 0;
- fm.needBits = 0;
- fm.device = 0;
- fm.numer.h = 1;
- fm.numer.v = 1;
- fm.denom.h = 1;
- fm.denom.v = 1;
-/*
- * For some reason, FMSwapFont alywas returns a structure where the returned font handle
- * is NULL. Until we figure this one out, assume all characters are allowed
- */
-
- fmOut = FMSwapFont(&fm);
- fHandle = fmOut->fontHandle;
- isMultiByteFont = subFontPtr->familyPtr->isMultiByteFont;
-
- /*
- * Found an outline font which has very complex font record.
- * Let's just assume *ALL* the characters are allowed.
- */
-
- end = (row + 1) << FONTMAP_SHIFT;
- for (i = row << FONTMAP_SHIFT; i < end; i++) {
- if (Tcl_UtfToExternal(NULL, encoding, src, Tcl_UniCharToUtf(i,
- src),
- TCL_ENCODING_STOPONERROR, NULL, (char *) buf,
- sizeof(buf),
- &srcRead, &dstWrote, NULL) == TCL_OK) {
- bitOffset = i & (FONTMAP_BITSPERPAGE - 1);
- subFontPtr->fontMap[row][bitOffset >> 3] |= 1
- << (bitOffset & 7);
- }
- }
-}
+#pragma mark -
+#pragma mark Accessors:
/*
*---------------------------------------------------------------------------
*
- * CanUseFallbackWithAliases --
+ * TkMacOSXNSFontForFont --
*
- * Helper function for FindSubFontForChar. Determine if the
- * specified face name (or an alias of the specified face name)
- * can be used to construct a screen font that can display the
- * given character.
+ * Return an NSFont for the given Tk_Font.
*
* Results:
- * See CanUseFallback().
+ * NSFont*.
*
* Side effects:
- * If the name and/or one of its aliases was rejected, the
- * rejected string is recorded in nameTriedPtr so that it won't
- * be tried again. The table of SubFonts might be extended, and if
- * a non-NULL reference to a subfont pointer is available, it is
- * updated if it previously pointed into the old subfont table.
+ * None.
*
*---------------------------------------------------------------------------
*/
-static SubFont *
-CanUseFallbackWithAliases(
- MacFont *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
- * reallocate our subfont table. */
+MODULE_SCOPE NSFont*
+TkMacOSXNSFontForFont(
+ Tk_Font tkfont)
{
- SubFont *subFontPtr;
- char **aliases;
- int i;
-
- if (SeenName(faceName, nameTriedPtr) == 0) {
- subFontPtr = CanUseFallback(fontPtr, faceName, ch, fixSubFontPtrPtr);
- if (subFontPtr != NULL) {
- return subFontPtr;
- }
- }
- aliases = TkFontGetAliasList(faceName);
- if (aliases != NULL) {
- for (i = 0; aliases[i] != NULL; i++) {
- if (SeenName(aliases[i], nameTriedPtr) == 0) {
- subFontPtr = CanUseFallback(fontPtr, aliases[i], ch,
- fixSubFontPtrPtr);
- if (subFontPtr != NULL) {
- return subFontPtr;
- }
- }
- }
- }
- return NULL;
+ return tkfont ? ((MacFont *)tkfont)->nsFont : nil;
}
/*
*---------------------------------------------------------------------------
*
- * SeenName --
+ * TkMacOSXNSFontAttributesForFont --
*
- * Used to determine we have already tried and rejected the given
- * face name when looking for a screen font that can support some
- * Unicode character.
+ * Return an NSDictionary of font attributes for the given Tk_Font.
*
* Results:
- * The return value is 0 if this face name has not already been seen,
- * non-zero otherwise.
+ * NSFont*.
*
* Side effects:
* None.
@@ -1857,388 +1131,92 @@ CanUseFallbackWithAliases(
*---------------------------------------------------------------------------
*/
-static int
-SeenName(
- const char *name, /* The name to check. */
- Tcl_DString *dsPtr) /* Contains names that have already been
- * seen. */
-{
- const char *seen, *end;
-
- seen = Tcl_DStringValue(dsPtr);
- end = seen + Tcl_DStringLength(dsPtr);
- while (seen < end) {
- if (strcasecmp(seen, name) == 0) {
- return 1;
- }
- seen += strlen(seen) + 1;
- }
- Tcl_DStringAppend(dsPtr, (char *) name, (int) (strlen(name) + 1));
- return 0;
-}
-
-/*
- *-------------------------------------------------------------------------
- *
- * CanUseFallback --
- *
- * If the specified physical screen font has not already been loaded
- * into the font object, determine if the specified physical screen
- * font can display the given character.
- *
- * Results:
- * The return value is a pointer to a newly allocated SubFont, owned
- * by the font object. This SubFont can be used to display the given
- * character. The SubFont represents the screen font with the base set
- * of font attributes from the font object, but using the specified
- * font name. NULL is returned if the font object already holds
- * a reference to the specified physical font or if the specified
- * physical font cannot display the given character.
- *
- * Side effects:
- * The font object's subFontArray is updated to contain a reference
- * to the newly allocated SubFont. The table of SubFonts might be
- * extended, and if a non-NULL reference to a subfont pointer is
- * available, it is updated if it previously pointed into the old
- * subfont table.
- *
- *-------------------------------------------------------------------------
- */
-
-static SubFont *
-CanUseFallback(
- MacFont *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. */
- SubFont **fixSubFontPtrPtr) /* Subfont reference to fix up if we
- * reallocate our subfont table. */
+MODULE_SCOPE NSDictionary*
+TkMacOSXNSFontAttributesForFont(
+ Tk_Font tkfont)
{
- int i;
- SubFont subFont;
- short faceNum;
-
- if (GetFamilyNum(faceName, &faceNum) == 0) {
- return NULL;
- }
-
- /*
- * Skip all fonts we've already used.
- */
-
- for (i = 0; i < fontPtr->numSubFonts; i++) {
- if (faceNum == fontPtr->subFontArray[i].familyPtr->faceNum) {
- return NULL;
- }
- }
-
- /*
- * Load this font and see if it has the desired character.
- */
-
- InitSubFont(fontPtr, faceNum, &subFont);
- if (((ch < 256) && (subFont.familyPtr->isSymbolFont))
- || (FontMapLookup(&subFont, ch) == 0)) {
- ReleaseSubFont(&subFont);
- return NULL;
- }
-
- if (fontPtr->numSubFonts >= SUBFONT_SPACE) {
- SubFont *newPtr = (SubFont *) ckalloc(sizeof(SubFont)
- * (fontPtr->numSubFonts + 1));
- memcpy((char *) newPtr, fontPtr->subFontArray,
- fontPtr->numSubFonts * sizeof(SubFont));
- if (fixSubFontPtrPtr != NULL) {
- /*
- * Fix up the variable pointed to by fixSubFontPtrPtr so it
- * still points into the live array. [Bug 618872]
- */
-
- *fixSubFontPtrPtr =
- newPtr + (*fixSubFontPtrPtr - fontPtr->subFontArray);
- }
- if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
- ckfree((char *) fontPtr->subFontArray);
- }
- fontPtr->subFontArray = newPtr;
- }
- fontPtr->subFontArray[fontPtr->numSubFonts] = subFont;
- fontPtr->numSubFonts++;
- return &fontPtr->subFontArray[fontPtr->numSubFonts - 1];
+ return tkfont ? ((MacFont *)tkfont)->nsAttributes : nil;
}
/*
- *-------------------------------------------------------------------------
+ *---------------------------------------------------------------------------
*
- * GetFamilyNum --
+ * TkMacOSXIsCharacterMissing --
*
- * Determines if any physical screen font exists on the system with
- * the given family name. If the family exists, then it should be
- * possible to construct some physical screen font with that family
- * name.
+ * Given a tkFont and a character determine whether the character has
+ * a glyph defined in the font or not.
*
* Results:
- * The return value is 0 if the specified font family does not exist,
- * non-zero otherwise. *faceNumPtr is filled with the unique face
- * number that identifies the screen font, or 0 if the font family
- * did not exist.
+ * Returns a 1 if the character is missing, a 0 if it is not.
*
* Side effects:
* None.
*
- *-------------------------------------------------------------------------
+ *---------------------------------------------------------------------------
*/
-static int
-GetFamilyNum(
- const char *faceName, /* UTF-8 name of font family to query. */
- short *faceNumPtr) /* Filled with font number for above family. */
-{
- FontNameMap *mapPtr;
-
- if (faceName != NULL) {
- for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) {
- if (strcasecmp(faceName, mapPtr->utfName) == 0) {
- *faceNumPtr = mapPtr->faceNum;
- return 1;
- }
- }
- }
- *faceNumPtr = 0;
- return 0;
-}
-
-static int
-GetFamilyOrAliasNum(
- const char *faceName, /* UTF-8 name of font family to query. */
- short *faceNumPtr) /* Filled with font number for above family. */
+int
+TkMacOSXIsCharacterMissing(
+ Tk_Font tkfont, /* The font we are looking in. */
+ unsigned int searchChar) /* The character we are looking for. */
{
- char **aliases;
- int i;
-
- if (GetFamilyNum(faceName, faceNumPtr) != 0) {
- return 1;
- }
- aliases = TkFontGetAliasList(faceName);
- if (aliases != NULL) {
- for (i = 0; aliases[i] != NULL; i++) {
- if (GetFamilyNum(aliases[i], faceNumPtr) != 0) {
- return 1;
- }
- }
- }
return 0;
}
/*
- *-------------------------------------------------------------------------
- *
- * GetUtfFaceName --
- *
- * Given the native name for a Macintosh font (in which the name of
- * the font is in the encoding of the font itself), return the UTF-8
- * name that corresponds to that font. The specified font name must
- * refer to a font that actually exists on the machine.
- *
- * This function is used to obtain the UTF-8 name when querying the
- * properties of a Macintosh font object.
- *
- * Results:
- * The return value is a pointer to the UTF-8 of the specified font.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------
- */
-
-static Tk_Uid
-GetUtfFaceName(
- StringPtr nativeName) /* Pascal name for font in native encoding. */
-{
- FontNameMap *mapPtr;
-
- for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) {
- if (pstrcmp(nativeName, mapPtr->nativeName) == 0) {
- return mapPtr->utfName;
- }
- }
- Tcl_Panic("GetUtfFaceName: unexpected nativeName");
- return NULL;
-}
-
-/*
- *------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
- * GetFontEncoding --
+ * TkMacOSXUseAntialiasedText --
*
- * Return a string that can be passed to Tcl_GetTextEncoding() and
- * used to convert bytes from UTF-8 into the encoding of the
- * specified font.
+ * Enables or disables application-wide use of antialiased text (where
+ * available). Sets up a linked Tcl global variable to allow
+ * disabling of antialiased text from tcl.
+ * The possible values for this variable are:
*
- * The desired encoding to use to convert the name of a symbolic
- * font into UTF-8 is macRoman, while the desired encoding to use
- * to convert bytes in a symbolic font to UTF-8 is the corresponding
- * symbolic encoding. Due to this dual interpretatation of symbolic
- * fonts, the caller can specify what type of encoding to return
- * should the specified font be symbolic.
+ * -1 - Use system default as configurable in "System Prefs" -> "General".
+ * 0 - Unconditionally disable antialiasing.
+ * 1 - Unconditionally enable antialiasing.
*
* Results:
- * The return value is a string that specifies the font's encoding.
- * If the font's encoding could not be identified, NULL is returned.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------
- */
-
-static Tcl_Encoding
-GetFontEncoding(
- int faceNum, /* Macintosh font number. */
- int allowSymbol, /* If non-zero, then the encoding string
- * for symbol fonts will be the corresponding
- * symbol encoding. Otherwise, the encoding
- * string for symbol fonts will be
- * "macRoman". */
- int *isSymbolPtr) /* Filled with non-zero if this font is a
- * symbol font, 0 otherwise. */
-{
- Str255 faceName;
- int script, lang;
- char *name;
-
- if (allowSymbol != 0) {
- GetFontName(faceNum, faceName);
- if (pstrcasecmp(faceName, "\psymbol") == 0) {
- *isSymbolPtr = 1;
- return Tcl_GetEncoding(NULL, "symbol");
- }
- if (pstrcasecmp(faceName, "\pzapf dingbats") == 0) {
- *isSymbolPtr = 1;
- return Tcl_GetEncoding(NULL, "macDingbats");
- }
- }
- *isSymbolPtr = 0;
- script = FontToScript(faceNum);
- lang = GetScriptVariable(script, smScriptLang);
- name = NULL;
- if (script == smRoman) {
- name = TkFindStateString(romanMap, lang);
- } else if (script == smCyrillic) {
- name = TkFindStateString(cyrillicMap, lang);
- }
- if (name == NULL) {
- name = TkFindStateString(scriptMap, script);
- }
- return Tcl_GetEncoding(NULL, name);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXInitControlFontStyle --
*
- * This procedure sets up the appropriate ControlFontStyleRec
- * for a Mac control.
- *
- * Results:
- * None.
+ * TCL_OK.
*
* Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkMacOSXInitControlFontStyle(
- Tk_Font tkfont,
- ControlFontStylePtr fsPtr)
-{
- MacFont *fontPtr = (MacFont *) tkfont;
- FontFamily *lastFamilyPtr = fontPtr->subFontArray[0].familyPtr;
-
- fsPtr->flags = kControlUseFontMask | kControlUseSizeMask |
- kControlUseFaceMask | kControlUseJustMask;
- fsPtr->font = lastFamilyPtr->faceNum;
- fsPtr->size = fontPtr->size;
- fsPtr->style = fontPtr->style;
- fsPtr->just = teCenter;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXUseAntialiasedText --
- *
- * Enables or disables application-wide use of quickdraw
- * antialiased text (where available).
- * Sets up a linked tcl global boolean variable with write trace
- * to allow disabling of antialiased text from tcl.
*
- * Results:
- * TCL_OK if facility was sucessfully enabled/disabled.
- * TCL_ERROR if an error occurred or if facility is not available.
- *
- * Side effects:
* None.
*
*----------------------------------------------------------------------
*/
-static int TkMacOSXAntialiasedTextEnabled = FALSE;
-
-static char *
-TkMacOSXAntialiasedTextVariableProc(
- ClientData clientData,
- Tcl_Interp *interp,
- const char *name1,
- const char *name2,
- int flags)
-{
- TkMacOSXUseAntialiasedText(interp, TkMacOSXAntialiasedTextEnabled);
- return (char *) NULL;
-}
-
-int
+MODULE_SCOPE int
TkMacOSXUseAntialiasedText(
- Tcl_Interp *interp,
- int enable)
+ Tcl_Interp * interp, /* The Tcl interpreter to receive the
+ * variable.*/
+ int enable) /* Initial value. */
{
static Boolean initialized = FALSE;
- static UInt32 (*swaptextflags)(UInt32) = NULL;
- if(!initialized) {
- swaptextflags = TkMacOSXGetNamedSymbol("QD", "_QDSwapTextFlags");
- if (!swaptextflags) {
- swaptextflags = TkMacOSXGetNamedSymbol("QD", "_SwapQDTextFlags");
- }
+ if (!initialized) {
initialized = TRUE;
- TkMacOSXAntialiasedTextEnabled = (swaptextflags ? enable : FALSE);
if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) {
Tcl_ResetResult(interp);
}
- if (Tcl_TraceVar(interp, "::tk::mac::antialiasedtext",
- TCL_GLOBAL_ONLY | TCL_TRACE_WRITES,
- TkMacOSXAntialiasedTextVariableProc, NULL) != TCL_OK) {
- Tcl_ResetResult(interp);
- }
if (Tcl_LinkVar(interp, "::tk::mac::antialiasedtext",
- (char *) &TkMacOSXAntialiasedTextEnabled,
- TCL_LINK_BOOLEAN) != TCL_OK) {
+ (char *) &antialiasedTextEnabled,
+ TCL_LINK_INT) != TCL_OK) {
Tcl_ResetResult(interp);
}
}
- if (swaptextflags) {
- swaptextflags(enable ? kQDUseCGTextRendering | kQDUseCGTextMetrics
- : kQDUseTrueTypeScalerGlyphs);
- TkMacOSXAntialiasedTextEnabled = enable;
- return TCL_OK;
- } else {
- TkMacOSXAntialiasedTextEnabled = FALSE;
- return TCL_ERROR;
- }
+ antialiasedTextEnabled = enable;
+ return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: objc
+ * c-basic-offset: 4
+ * fill-column: 79
+ * coding: utf-8
+ * End:
+ */