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-2020 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 value_data_size,
195 value_name_length;
196
197 char
198 value_data[MagickPathExtent],
199 value_name[MagickPathExtent];
200
201 res = ERROR_SUCCESS;
202
203 while (res != ERROR_NO_MORE_ITEMS)
204 {
205 char
206 *family_extent,
207 token[MagickPathExtent],
208 *pos,
209 *q;
210
211 value_name_length = sizeof(value_name) - 1;
212 value_data_size = sizeof(value_data) - 1;
213 res = RegEnumValueA ( reg_key, registry_index, value_name,
214 &value_name_length, 0, &type, (BYTE*)value_data, &value_data_size);
215 registry_index++;
216 if (res != ERROR_SUCCESS)
217 continue;
218 if ( (pos = strstr(value_name, " (TrueType)")) == (char*) NULL )
219 continue;
220 *pos='\0'; /* Remove (TrueType) from string */
221
222 type_info=(TypeInfo *) AcquireCriticalMemory(sizeof(*type_info));
223 (void) memset(type_info,0,sizeof(TypeInfo));
224
225 type_info->path=ConstantString("Windows Fonts");
226 type_info->signature=MagickCoreSignature;
227
228 /* Name */
229 (void) CopyMagickString(buffer,value_name,MagickPathExtent);
230 for(pos = buffer; *pos != 0 ; pos++)
231 if (*pos == ' ')
232 *pos = '-';
233 type_info->name=ConstantString(buffer);
234
235 /* Fullname */
236 type_info->description=ConstantString(value_name);
237
238 /* Format */
239 type_info->format=ConstantString("truetype");
240
241 /* Glyphs */
242 if (strchr(value_data,'\\') != (char *) NULL)
243 (void) CopyMagickString(buffer,value_data,MagickPathExtent);
244 else
245 {
246 (void) CopyMagickString(buffer,font_root,MagickPathExtent);
247 (void) ConcatenateMagickString(buffer,value_data,MagickPathExtent);
248 }
249
250 LocaleLower(buffer);
251 type_info->glyphs=ConstantString(buffer);
252
253 type_info->stretch=NormalStretch;
254 type_info->style=NormalStyle;
255 type_info->weight=400;
256
257 /* Some fonts are known to require special encodings */
258 if ( (LocaleCompare(type_info->name, "Symbol") == 0 ) ||
259 (LocaleCompare(type_info->name, "Wingdings") == 0 ) ||
260 (LocaleCompare(type_info->name, "Wingdings-2") == 0 ) ||
261 (LocaleCompare(type_info->name, "Wingdings-3") == 0 ) )
262 type_info->encoding=ConstantString("AppleRoman");
263
264 family_extent=value_name;
265
266 for (q=value_name; *q != '\0'; )
267 {
268 (void) GetNextToken(q,(const char **) &q,MagickPathExtent,token);
269 if (*token == '\0')
270 break;
271
272 if (LocaleCompare(token,"Italic") == 0)
273 {
274 type_info->style=ItalicStyle;
275 }
276
277 else if (LocaleCompare(token,"Oblique") == 0)
278 {
279 type_info->style=ObliqueStyle;
280 }
281
282 else if (LocaleCompare(token,"Bold") == 0)
283 {
284 type_info->weight=700;
285 }
286
287 else if (LocaleCompare(token,"Thin") == 0)
288 {
289 type_info->weight=100;
290 }
291
292 else if ( (LocaleCompare(token,"ExtraLight") == 0) ||
293 (LocaleCompare(token,"UltraLight") == 0) )
294 {
295 type_info->weight=200;
296 }
297
298 else if (LocaleCompare(token,"Light") == 0)
299 {
300 type_info->weight=300;
301 }
302
303 else if ( (LocaleCompare(token,"Normal") == 0) ||
304 (LocaleCompare(token,"Regular") == 0) )
305 {
306 type_info->weight=400;
307 }
308
309 else if (LocaleCompare(token,"Medium") == 0)
310 {
311 type_info->weight=500;
312 }
313
314 else if ( (LocaleCompare(token,"SemiBold") == 0) ||
315 (LocaleCompare(token,"DemiBold") == 0) )
316 {
317 type_info->weight=600;
318 }
319
320 else if ( (LocaleCompare(token,"ExtraBold") == 0) ||
321 (LocaleCompare(token,"UltraBold") == 0) )
322 {
323 type_info->weight=800;
324 }
325
326 else if ( (LocaleCompare(token,"Heavy") == 0) ||
327 (LocaleCompare(token,"Black") == 0) )
328 {
329 type_info->weight=900;
330 }
331
332 else if (LocaleCompare(token,"Condensed") == 0)
333 {
334 type_info->stretch = CondensedStretch;
335 }
336
337 else if (LocaleCompare(token,"Expanded") == 0)
338 {
339 type_info->stretch = ExpandedStretch;
340 }
341
342 else if (LocaleCompare(token,"ExtraCondensed") == 0)
343 {
344 type_info->stretch = ExtraCondensedStretch;
345 }
346
347 else if (LocaleCompare(token,"ExtraExpanded") == 0)
348 {
349 type_info->stretch = ExtraExpandedStretch;
350 }
351
352 else if (LocaleCompare(token,"SemiCondensed") == 0)
353 {
354 type_info->stretch = SemiCondensedStretch;
355 }
356
357 else if (LocaleCompare(token,"SemiExpanded") == 0)
358 {
359 type_info->stretch = SemiExpandedStretch;
360 }
361
362 else if (LocaleCompare(token,"UltraCondensed") == 0)
363 {
364 type_info->stretch = UltraCondensedStretch;
365 }
366
367 else if (LocaleCompare(token,"UltraExpanded") == 0)
368 {
369 type_info->stretch = UltraExpandedStretch;
370 }
371
372 else
373 {
374 family_extent=q;
375 }
376 }
377
378 (void) CopyMagickString(buffer,value_name,family_extent-value_name+1);
379 StripString(buffer);
380 type_info->family=ConstantString(buffer);
381
382 list_entries++;
383 status=AddValueToSplayTree(type_cache,type_info->name,type_info);
384 if (status == MagickFalse)
385 (void) ThrowMagickException(exception,GetMagickModule(),
386 ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name);
387 }
388 }
389 RegCloseKey ( reg_key );
390 return(MagickTrue);
391 }
392
393 #endif
394