File: tk2fonts.R

package info (click to toggle)
r-cran-tcltk2 1.2-10-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 5,356 kB
  • ctags: 1,386
  • sloc: tcl: 37,888; ansic: 792; python: 324; sh: 68; sed: 16; makefile: 1
file content (251 lines) | stat: -rwxr-xr-x 9,912 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
### tk2Fonts.R - Manage Tk fonts
### Copyright (c), Philippe Grosjean (phgrosjean@sciviews.org)
### Licensed under LGPL 3 or above
###
### Changes:
### - 2009-04-23: fix of a bug in fntl$family, $ operator not allowed (thanks Brian Ripley)
### - 2007-01-11: fisrt version (for tcltk2_1.0-0)
###
### To do:
### -

tk2font.get <- function (font, what = c("family", "size", "bold", "italic"))
{
	## font is the TkFont name to use, in case of several items, other ones
	## are secondary, tertiary, ... options
	## what indicate what characteristic of the font to report in the list
	## 'family', 'size', 'bold', 'italic', 'underline', 'overstrike' (last two rarely used)
	if (!is.tk()) return("")
	allTkFonts <- as.character(tkfont.names())
	for (fnt in font) {
		if (fnt %in% allTkFonts) break
	}
	if (!fnt %in% allTkFonts) {
		return("")
		##if (length(font) == 1) {
		##	stop("'", font, "' is not currently defined in Tk")
		##} else {
		##	stop("'", paste(font, collapse = "', '"), "' are not currently defined in Tk")
		##}
	}
	fontspec <- as.character(tkfont.configure(fnt))
	res <- list()
	if (length(fontspec) != 12) return(res)	# There is a problem here!
	if ("family" %in% what) res$family <- fontspec[2]
	if ("size" %in% what) res$size <- as.numeric(fontspec[4])
	if ("bold" %in% what) res$bold <- (fontspec[6] == "bold")
	if ("italic" %in% what) res$italic <- (fontspec[8] == "italic")
	if ("underline" %in% what) res$underline <- (fontspec[10] == "1")
	if ("overstrike" %in% what) res$overstrike <- (fontspec[12] == "1")
	return(res)
}

tk2font.set  <- function (font, settings)
{
### TODO: allow for multiple fonts specifications => take first one available
	## font is the name of the TkFont to create/change
	## settings is a list with font characteristics
	if (!is.tk()) return(NULL)
	font <- as.character(font)
	l <- length(font)
	if (!is.list(settings) && !is.character(settings))
		stop("'settings' must be a list or a character string")
	## If settings is a character string,
	## it is assumed to be a text description of a Tk font
	if (is.character(settings)) {
		## Do not recycle... make sure that lengths match
		if (length(settings) != l)
			stop("length of 'font' and 'settings' do not match")
		for (i in 1:l) {
			.Tcl(paste("catch {font create ", font[i], "}", sep = ""))
			.Tcl(paste("catch {font configure ", font[i], " ", settings[i], "}",
				sep = ""))
		}
	} else {  # This is a list of font characteristics
		## Do not recycle... make sure that lengths match
		if (l > 1) {
			if (length(settings) != l)
				stop("length of 'font' and 'settings' do not match")
		} else {  # Is it the list of characteristics, or a lit containing it?
			if (any(names(settings) %in%
				c("family", "size", "bold", "italic", "underline", "overstrike")))
				settings <- list(settings)
		}
		fntfamilies <- as.character(tkfont.families())
		for (i in 1:l) {
			## Construct the font descriptor
			fntl <- as.list(settings[[i]])
			fnt <- " "
			if (!is.null(fntl$family)) {
				## Look for the first font family provided that is available
				fntfamily <- fntl$family
				if (length(fntfamily) > 1) {
					fntexists <- fntfamily %in% fntfamilies
					if (any(fntexists)) fntfamily <- fntfamily[fntexists][1] else
						fntfamily <- fntfamily[1]  # No fonts found... take first one
				}
			 	fnt <- paste(fnt, "-family {", fntfamily, "}", sep = "")
			}
			if (!is.null(fntl$size)) fnt <- paste(fnt, "-size", fntl$size)
			if (!is.null(fntl$bold)) {
				value <- if(fntl$bold == TRUE) "bold" else "normal"
				fnt <- paste(fnt, "-weight", value)
			}
			if (!is.null(fntl$italic)) {
				value <- if(fntl$italic == TRUE) "italic" else "roman"
				fnt <- paste(fnt, "-slant", value)
			}
			if (!is.null(fntl$underline)) fnt <- paste(fnt, "-underline",
				as.numeric(fntl$underline == TRUE))
			if (!is.null(fntl$overstrike)) fnt <- paste(fnt, "-overstrike",
				as.numeric(fntl$overstrike == TRUE))
			## Possibly create the font in Tk
			.Tcl(paste("catch {font create ", font[i], "}", sep = ""))
			if (fnt != " ")
				.Tcl(paste("catch {font configure ", font[i], fnt, "}", sep = ""))
		}
	}
	res <- font %in% as.character(tkfont.names())
	names(res) <- font
	return(res)
}

tk2font.setstyle <- function (text = TRUE, system = FALSE, default.styles = FALSE)
{
	## Set default fonts according to currently defined style
	## .SystemFonts and .Fonts must be defined in SciViews:TempEnv!

	if (!is.tk()) {
		warning("Package Tk is required but not loaded")
		return(NULL)
	}

	## This is a copy of assignTemp(), getTemp() and existsTemp() functions from
	## svMisc, so that we do not link to this package
	TempEnv <- function () {
	    pos <-  match("SciViews:TempEnv", search())
	    if (is.na(pos)) { # Must create it
	        `SciViews:TempEnv` <- list()
	        Attach <- function (...) get("attach", mode = "function")(...)
			Attach(`SciViews:TempEnv`, pos = length(search()) - 1)
	        rm(`SciViews:TempEnv`)
	        pos <- match("SciViews:TempEnv", search())
	    }
	    return(pos.to.env(pos))
	}
	
	assignTemp <- function (x, value, replace.existing = TRUE)
	    if (replace.existing || !exists(x, envir = TempEnv(), mode = "any", inherits = FALSE))
	        assign(x, value, envir = TempEnv())
	
	existsTemp <- function (x, mode = "any")
	    exists(x, envir = TempEnv(), mode = mode, inherits = FALSE)
	
	getTemp <- function (x, default = NULL, mode="any") {
	    if  (exists(x, envir = TempEnv(), mode = mode, inherits = FALSE)) {
	        return(get(x, envir = TempEnv(), mode = mode, inherits = FALSE))
	    } else {  # Variable not found, return the default value
	        return(default)
	    }
	}

	if (system) {  # Set system fonts
		## We collect back system fonts settings (other values may be imposed by Tk)
		sysfonts <- list(
			defaultclassic = tk2font.get("TkClassicDefaultFont"),
			default = tk2font.get("TkDefaultFont"),
			caption = tk2font.get("TkCaptionFont"),
			smallcaption = tk2font.get(c("TkSmallCaptionFont", "TkCaptionFont")),
			menu = tk2font.get(c("TkMenuFont", "TkDefaultFont")),
			status = tk2font.get(c("TkStatusFont", "TkTooltipFont")),
			tooltip = tk2font.get("TkTooltipFont"),
			heading = tk2font.get("TkHeadingFont"),
			icon = tk2font.get(c("TkIconFont", "TkDefaultFont"))
		)
		## Make sure these are correctly defined
		assignTemp(".SystemFonts", sysfonts)
		res <- TRUE
	} else res <- character(0)

	if (default.styles) {  # Define default styles
		## These are the four default Font themes one can use
		assignTemp(".FontsStyleClassic", list(
			Text = list(family = c("Times New Roman", "Times"), size = -12),
			Title = list(family = c("Arial", "Helvetica"), size = -14, bold = TRUE),
			BigTitle = list(family = c("Arial", "Helvetica"), size = -16, bold = TRUE),
			Fixed = list(family = c("Courier New", "Courier"), size = -12)
		))

		assignTemp(".FontsStyleAlternate", list(
			Text = list(family = "Georgia", alt.family = "Times", size = -12),
			Title = list(family = c("Trebuchet MS", "Trebuchet"),
				alt.family = "Helvetica", size = -14, bold = TRUE),
			BigTitle = list(family = c("Trebuchet MS", "Trebuchet"),
				alt.family = "Helvetica", size = -16, bold = TRUE),
			Fixed = list(family = "Andale Mono", alt.family = "Courier", size = -12)
		))

		assignTemp(".FontsStylePresentation", list(
			Text = list(family = "Verdana", alt.family = "Helvetica", size = -12),
			Title = list(family = "Verdana", alt.family = "Helvetica", size = -14,
				bold = TRUE),
			BigTitle = list(family = "Verdana", alt.family = "Helvetica", size = -16,
				bold = TRUE),
			Fixed = list(family = "Lucida Console", alt.family = "Courier",
				size = -12)
		))

		assignTemp(".FontsStyleFancy", list(
			Text = list(family = c("Trebuchet MS", "Trebuchet"),
				alt.family = "Helvetica", size = -12),
			Title = list(family = c("Comic Sans MS", "Comic Sans"),
				alt.family = "Helvetica", size = -14, bold = TRUE),
			BigTitle = list(family = c("Comic Sans MS", "Comic Sans"),
				alt.family = "Helvetica", size = -16, bold = TRUE),
			Fixed = list(family = "Lucida Console", alt.family = "Courier",
				size = -12)
		))
	}

	if (text) {  # Set text, titles and fixed fonts
		## Determine which font style we currently use
		curStyle <- getTemp(".FontsStyle", default = "Classic", mode = "character")
		curSFonts <- getTemp(paste(".FontsStyle", curStyle, sep = ""),
			default = getTemp(".FontsStyleClassic"))
		assignTemp(".Fonts", curSFonts)

		## Create corresponding fonts in Tk (note, we create bold, italic, and
		## bolditalic equivalents for TkTextFont and TkFixedFont
		Fonts <- list()
		Fonts$Text <- curSFonts$Text
		Fonts$Text$bold <- FALSE
		Fonts$Text$italic <- FALSE
		Fonts$TextBold <- Fonts$Text
		Fonts$TextBold$bold <- TRUE
		Fonts$TextItalic <- Fonts$Text
		Fonts$TextItalic$italic <- TRUE
		Fonts$TextBoldItalic <- Fonts$TextBold
		Fonts$TextBoldItalic$italic <- TRUE
		Fonts$Title <- curSFonts$Title
		Fonts$BigTitle <- curSFonts$BigTitle
		Fonts$Fixed <- curSFonts$Fixed
		Fonts$Fixed$bold <- FALSE
		Fonts$Fixed$italic <- FALSE
		Fonts$FixedBold <- Fonts$Fixed
		Fonts$FixedBold$bold <- TRUE
		Fonts$FixedItalic <- Fonts$Fixed
		Fonts$FixedItalic$italic <- TRUE
		Fonts$FixedBoldItalic <- Fonts$FixedBold
		Fonts$FixedBoldItalic$italic <- TRUE

		FNames <- c("TkTextFont", "TkTextBoldFont", "TkTextItalicFont",
			"TkTextBoldItalicFont", "TkTitleFont", "TkBigTitleFont", "TkFixedFont",
			"TkFixedBoldFont", "TkFixedItalicFont", "TkFixedBoldItalicFont")
		res <- c(res, tk2font.set(FNames, Fonts))
	}
	## Check the results
	if (system && any(!res))
		warning("One or several Tk fonts not set: '",
			paste(names(res)[!res], collapse = "', '", "'"))
	return(res)
}