1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % %
7 % N N TTTTT %
8 % NN N T %
9 % N N N T %
10 % N NN T %
11 % N N T %
12 % %
13 % %
14 % Windows NT Feature Methods for MagickCore %
15 % %
16 % Software Design %
17 % Cristy %
18 % December 1996 %
19 % %
20 % %
21 % Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization %
22 % dedicated to making software imaging solutions freely available. %
23 % %
24 % You may not use this file except in compliance with the License. You may %
25 % obtain a copy of the License at %
26 % %
27 % https://imagemagick.org/script/license.php %
28 % %
29 % Unless required by applicable law or agreed to in writing, software %
30 % distributed under the License is distributed on an "AS IS" BASIS, %
31 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
32 % See the License for the specific language governing permissions and %
33 % limitations under the License. %
34 % %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %
37 %
38 */
39
40 /*
41 Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
45 #define WIN32_LEAN_AND_MEAN
46 #define VC_EXTRALEAN
47 #include <windows.h>
48 #include "MagickCore/cache.h"
49 #include "MagickCore/colorspace.h"
50 #include "MagickCore/colorspace-private.h"
51 #include "MagickCore/draw.h"
52 #include "MagickCore/exception.h"
53 #include "MagickCore/exception-private.h"
54 #include "MagickCore/image-private.h"
55 #include "MagickCore/memory_.h"
56 #include "MagickCore/memory-private.h"
57 #include "MagickCore/monitor.h"
58 #include "MagickCore/monitor-private.h"
59 #include "MagickCore/nt-base.h"
60 #include "MagickCore/nt-base-private.h"
61 #include "MagickCore/pixel-accessor.h"
62 #include "MagickCore/quantum.h"
63 #include "MagickCore/string_.h"
64 #include "MagickCore/token.h"
65 #include "MagickCore/splay-tree.h"
66 #include "MagickCore/utility.h"
67
68 /*
69 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70 % %
71 % %
72 % %
73 % I s M a g i c k C o n f l i c t %
74 % %
75 % %
76 % %
77 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 %
79 % IsMagickConflict() returns true if the image format conflicts with a logical
80 % drive (.e.g. X:).
81 %
82 % The format of the IsMagickConflict method is:
83 %
84 % MagickBooleanType IsMagickConflict(const char *magick)
85 %
86 % A description of each parameter follows:
87 %
88 % o magick: Specifies the image format.
89 %
90 */
NTIsMagickConflict(const char * magick)91 MagickExport MagickBooleanType NTIsMagickConflict(const char *magick)
92 {
93 MagickBooleanType
94 status;
95
96 assert(magick != (char *) NULL);
97 if (strlen(magick) > 1)
98 return(MagickFalse);
99 status=(GetLogicalDrives() & (1 << ((LocaleUppercase((int)
100 (*magick)))-'A'))) != 0 ? MagickTrue : MagickFalse;
101 return(status);
102 }
103
104 /*
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 % %
107 % %
108 % %
109 % N T A c q u i r e T y p e C a c h e %
110 % %
111 % %
112 % %
113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 %
115 % NTAcquireTypeCache() loads a Windows TrueType fonts.
116 %
117 % The format of the NTAcquireTypeCache method is:
118 %
119 % MagickBooleanType NTAcquireTypeCache(SplayTreeInfo *type_cache)
120 %
121 % A description of each parameter follows:
122 %
123 % o type_cache: A linked list of fonts.
124 %
125 */
NTAcquireTypeCache(SplayTreeInfo * type_cache,ExceptionInfo * exception)126 MagickExport MagickBooleanType NTAcquireTypeCache(SplayTreeInfo *type_cache,
127 ExceptionInfo *exception)
128 {
129 HKEY
130 reg_key = (HKEY) INVALID_HANDLE_VALUE;
131
132 LONG
133 res;
134
135 int
136 list_entries = 0;
137
138 char
139 buffer[MagickPathExtent],
140 system_root[MagickPathExtent],
141 font_root[MagickPathExtent];
142
143 DWORD
144 type,
145 system_root_length;
146
147 MagickBooleanType
148 status;
149
150 /*
151 Try to find the right Windows*\CurrentVersion key, the SystemRoot and
152 then the Fonts key
153 */
154 res = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
155 "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, ®_key);
156 if (res == ERROR_SUCCESS) {
157 system_root_length=sizeof(system_root)-1;
158 res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type,
159 (BYTE*) system_root, &system_root_length);
160 }
161 if (res != ERROR_SUCCESS) {
162 res = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
163 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, ®_key);
164 if (res == ERROR_SUCCESS) {
165 system_root_length=sizeof(system_root)-1;
166 res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type,
167 (BYTE*)system_root, &system_root_length);
168 }
169 }
170 if (res == ERROR_SUCCESS)
171 res = RegOpenKeyExA (reg_key, "Fonts",0, KEY_READ, ®_key);
172 if (res != ERROR_SUCCESS)
173 return(MagickFalse);
174 *font_root='\0';
175 (void) CopyMagickString(buffer,system_root,MagickPathExtent);
176 (void) ConcatenateMagickString(buffer,"\\fonts\\arial.ttf",MagickPathExtent);
177 if (IsPathAccessible(buffer) != MagickFalse)
178 {
179 (void) CopyMagickString(font_root,system_root,MagickPathExtent);
180 (void) ConcatenateMagickString(font_root,"\\fonts\\",MagickPathExtent);
181 }
182 else
183 {
184 (void) CopyMagickString(font_root,system_root,MagickPathExtent);
185 (void) ConcatenateMagickString(font_root,"\\",MagickPathExtent);
186 }
187
188 {
189 TypeInfo
190 *type_info;
191
192 DWORD
193 registry_index = 0,
194 type,
195 value_data_size,
196 value_name_length;
197
198 char
199 value_data[MagickPathExtent],
200 value_name[MagickPathExtent];
201
202 res = ERROR_SUCCESS;
203
204 while (res != ERROR_NO_MORE_ITEMS)
205 {
206 char
207 *family_extent,
208 token[MagickPathExtent],
209 *pos,
210 *q;
211
212 value_name_length = sizeof(value_name) - 1;
213 value_data_size = sizeof(value_data) - 1;
214 res = RegEnumValueA ( reg_key, registry_index, value_name,
215 &value_name_length, 0, &type, (BYTE*)value_data, &value_data_size);
216 registry_index++;
217 if (res != ERROR_SUCCESS)
218 continue;
219 if ( (pos = strstr(value_name, " (TrueType)")) == (char*) NULL )
220 continue;
221 *pos='\0'; /* Remove (TrueType) from string */
222
223 type_info=(TypeInfo *) AcquireCriticalMemory(sizeof(*type_info));
224 (void) memset(type_info,0,sizeof(TypeInfo));
225
226 type_info->path=ConstantString("Windows Fonts");
227 type_info->signature=MagickCoreSignature;
228
229 /* Name */
230 (void) CopyMagickString(buffer,value_name,MagickPathExtent);
231 for(pos = buffer; *pos != 0 ; pos++)
232 if (*pos == ' ')
233 *pos = '-';
234 type_info->name=ConstantString(buffer);
235
236 /* Fullname */
237 type_info->description=ConstantString(value_name);
238
239 /* Format */
240 type_info->format=ConstantString("truetype");
241
242 /* Glyphs */
243 if (strchr(value_data,'\\') != (char *) NULL)
244 (void) CopyMagickString(buffer,value_data,MagickPathExtent);
245 else
246 {
247 (void) CopyMagickString(buffer,font_root,MagickPathExtent);
248 (void) ConcatenateMagickString(buffer,value_data,MagickPathExtent);
249 }
250
251 LocaleLower(buffer);
252 type_info->glyphs=ConstantString(buffer);
253
254 type_info->stretch=NormalStretch;
255 type_info->style=NormalStyle;
256 type_info->weight=400;
257
258 /* Some fonts are known to require special encodings */
259 if ( (LocaleCompare(type_info->name, "Symbol") == 0 ) ||
260 (LocaleCompare(type_info->name, "Wingdings") == 0 ) ||
261 (LocaleCompare(type_info->name, "Wingdings-2") == 0 ) ||
262 (LocaleCompare(type_info->name, "Wingdings-3") == 0 ) )
263 type_info->encoding=ConstantString("AppleRoman");
264
265 family_extent=value_name;
266
267 for (q=value_name; *q != '\0'; )
268 {
269 GetNextToken(q,(const char **) &q,MagickPathExtent,token);
270 if (*token == '\0')
271 break;
272
273 if (LocaleCompare(token,"Italic") == 0)
274 {
275 type_info->style=ItalicStyle;
276 }
277
278 else if (LocaleCompare(token,"Oblique") == 0)
279 {
280 type_info->style=ObliqueStyle;
281 }
282
283 else if (LocaleCompare(token,"Bold") == 0)
284 {
285 type_info->weight=700;
286 }
287
288 else if (LocaleCompare(token,"Thin") == 0)
289 {
290 type_info->weight=100;
291 }
292
293 else if ( (LocaleCompare(token,"ExtraLight") == 0) ||
294 (LocaleCompare(token,"UltraLight") == 0) )
295 {
296 type_info->weight=200;
297 }
298
299 else if (LocaleCompare(token,"Light") == 0)
300 {
301 type_info->weight=300;
302 }
303
304 else if ( (LocaleCompare(token,"Normal") == 0) ||
305 (LocaleCompare(token,"Regular") == 0) )
306 {
307 type_info->weight=400;
308 }
309
310 else if (LocaleCompare(token,"Medium") == 0)
311 {
312 type_info->weight=500;
313 }
314
315 else if ( (LocaleCompare(token,"SemiBold") == 0) ||
316 (LocaleCompare(token,"DemiBold") == 0) )
317 {
318 type_info->weight=600;
319 }
320
321 else if ( (LocaleCompare(token,"ExtraBold") == 0) ||
322 (LocaleCompare(token,"UltraBold") == 0) )
323 {
324 type_info->weight=800;
325 }
326
327 else if ( (LocaleCompare(token,"Heavy") == 0) ||
328 (LocaleCompare(token,"Black") == 0) )
329 {
330 type_info->weight=900;
331 }
332
333 else if (LocaleCompare(token,"Condensed") == 0)
334 {
335 type_info->stretch = CondensedStretch;
336 }
337
338 else if (LocaleCompare(token,"Expanded") == 0)
339 {
340 type_info->stretch = ExpandedStretch;
341 }
342
343 else if (LocaleCompare(token,"ExtraCondensed") == 0)
344 {
345 type_info->stretch = ExtraCondensedStretch;
346 }
347
348 else if (LocaleCompare(token,"ExtraExpanded") == 0)
349 {
350 type_info->stretch = ExtraExpandedStretch;
351 }
352
353 else if (LocaleCompare(token,"SemiCondensed") == 0)
354 {
355 type_info->stretch = SemiCondensedStretch;
356 }
357
358 else if (LocaleCompare(token,"SemiExpanded") == 0)
359 {
360 type_info->stretch = SemiExpandedStretch;
361 }
362
363 else if (LocaleCompare(token,"UltraCondensed") == 0)
364 {
365 type_info->stretch = UltraCondensedStretch;
366 }
367
368 else if (LocaleCompare(token,"UltraExpanded") == 0)
369 {
370 type_info->stretch = UltraExpandedStretch;
371 }
372
373 else
374 {
375 family_extent=q;
376 }
377 }
378
379 (void) CopyMagickString(buffer,value_name,family_extent-value_name+1);
380 StripString(buffer);
381 type_info->family=ConstantString(buffer);
382
383 list_entries++;
384 status=AddValueToSplayTree(type_cache,type_info->name,type_info);
385 if (status == MagickFalse)
386 (void) ThrowMagickException(exception,GetMagickModule(),
387 ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name);
388 }
389 }
390 RegCloseKey ( reg_key );
391 return(MagickTrue);
392 }
393
394 #endif
395