2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14 % Windows NT Feature Methods for MagickCore %
21 % Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization %
22 % dedicated to making software imaging solutions freely available. %
24 % You may not use this file except in compliance with the License. You may %
25 % obtain a copy of the License at %
27 % https://imagemagick.org/script/license.php %
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. %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "MagickCore/studio.h"
44 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
45 #define WIN32_LEAN_AND_MEAN
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"
69 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 % I s M a g i c k C o n f l i c t %
77 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79 % IsMagickConflict() returns true if the image format conflicts with a logical
82 % The format of the IsMagickConflict method is:
84 % MagickBooleanType IsMagickConflict(const char *magick)
86 % A description of each parameter follows:
88 % o magick: Specifies the image format.
91 MagickExport MagickBooleanType NTIsMagickConflict(const char *magick)
96 assert(magick != (char *) NULL);
97 if (strlen(magick) > 1)
99 status=(GetLogicalDrives() & (1 << ((LocaleUppercase((int)
100 (*magick)))-'A'))) != 0 ? MagickTrue : MagickFalse;
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109 % N T A c q u i r e T y p e C a c h e %
113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
115 % NTAcquireTypeCache() loads a Windows TrueType fonts.
117 % The format of the NTAcquireTypeCache method is:
119 % MagickBooleanType NTAcquireTypeCache(SplayTreeInfo *type_cache)
121 % A description of each parameter follows:
123 % o type_cache: A linked list of fonts.
126 MagickExport MagickBooleanType NTAcquireTypeCache(SplayTreeInfo *type_cache,
127 ExceptionInfo *exception)
130 reg_key = (HKEY) INVALID_HANDLE_VALUE;
139 buffer[MagickPathExtent],
140 system_root[MagickPathExtent],
141 font_root[MagickPathExtent];
151 Try to find the right Windows*\CurrentVersion key, the SystemRoot and
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);
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);
170 if (res == ERROR_SUCCESS)
171 res = RegOpenKeyExA (reg_key, "Fonts",0, KEY_READ, ®_key);
172 if (res != ERROR_SUCCESS)
175 (void) CopyMagickString(buffer,system_root,MagickPathExtent);
176 (void) ConcatenateMagickString(buffer,"\\fonts\\arial.ttf",MagickPathExtent);
177 if (IsPathAccessible(buffer) != MagickFalse)
179 (void) CopyMagickString(font_root,system_root,MagickPathExtent);
180 (void) ConcatenateMagickString(font_root,"\\fonts\\",MagickPathExtent);
184 (void) CopyMagickString(font_root,system_root,MagickPathExtent);
185 (void) ConcatenateMagickString(font_root,"\\",MagickPathExtent);
198 value_data[MagickPathExtent],
199 value_name[MagickPathExtent];
203 while (res != ERROR_NO_MORE_ITEMS)
207 token[MagickPathExtent],
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);
216 if (res != ERROR_SUCCESS)
218 if ( (pos = strstr(value_name, " (TrueType)")) == (char*) NULL )
220 *pos='\0'; /* Remove (TrueType) from string */
222 type_info=(TypeInfo *) AcquireCriticalMemory(sizeof(*type_info));
223 (void) memset(type_info,0,sizeof(TypeInfo));
225 type_info->path=ConstantString("Windows Fonts");
226 type_info->signature=MagickCoreSignature;
229 (void) CopyMagickString(buffer,value_name,MagickPathExtent);
230 for(pos = buffer; *pos != 0 ; pos++)
233 type_info->name=ConstantString(buffer);
236 type_info->description=ConstantString(value_name);
239 type_info->format=ConstantString("truetype");
242 if (strchr(value_data,'\\') != (char *) NULL)
243 (void) CopyMagickString(buffer,value_data,MagickPathExtent);
246 (void) CopyMagickString(buffer,font_root,MagickPathExtent);
247 (void) ConcatenateMagickString(buffer,value_data,MagickPathExtent);
251 type_info->glyphs=ConstantString(buffer);
253 type_info->stretch=NormalStretch;
254 type_info->style=NormalStyle;
255 type_info->weight=400;
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");
264 family_extent=value_name;
266 for (q=value_name; *q != '\0'; )
268 (void) GetNextToken(q,(const char **) &q,MagickPathExtent,token);
272 if (LocaleCompare(token,"Italic") == 0)
274 type_info->style=ItalicStyle;
277 else if (LocaleCompare(token,"Oblique") == 0)
279 type_info->style=ObliqueStyle;
282 else if (LocaleCompare(token,"Bold") == 0)
284 type_info->weight=700;
287 else if (LocaleCompare(token,"Thin") == 0)
289 type_info->weight=100;
292 else if ( (LocaleCompare(token,"ExtraLight") == 0) ||
293 (LocaleCompare(token,"UltraLight") == 0) )
295 type_info->weight=200;
298 else if (LocaleCompare(token,"Light") == 0)
300 type_info->weight=300;
303 else if ( (LocaleCompare(token,"Normal") == 0) ||
304 (LocaleCompare(token,"Regular") == 0) )
306 type_info->weight=400;
309 else if (LocaleCompare(token,"Medium") == 0)
311 type_info->weight=500;
314 else if ( (LocaleCompare(token,"SemiBold") == 0) ||
315 (LocaleCompare(token,"DemiBold") == 0) )
317 type_info->weight=600;
320 else if ( (LocaleCompare(token,"ExtraBold") == 0) ||
321 (LocaleCompare(token,"UltraBold") == 0) )
323 type_info->weight=800;
326 else if ( (LocaleCompare(token,"Heavy") == 0) ||
327 (LocaleCompare(token,"Black") == 0) )
329 type_info->weight=900;
332 else if (LocaleCompare(token,"Condensed") == 0)
334 type_info->stretch = CondensedStretch;
337 else if (LocaleCompare(token,"Expanded") == 0)
339 type_info->stretch = ExpandedStretch;
342 else if (LocaleCompare(token,"ExtraCondensed") == 0)
344 type_info->stretch = ExtraCondensedStretch;
347 else if (LocaleCompare(token,"ExtraExpanded") == 0)
349 type_info->stretch = ExtraExpandedStretch;
352 else if (LocaleCompare(token,"SemiCondensed") == 0)
354 type_info->stretch = SemiCondensedStretch;
357 else if (LocaleCompare(token,"SemiExpanded") == 0)
359 type_info->stretch = SemiExpandedStretch;
362 else if (LocaleCompare(token,"UltraCondensed") == 0)
364 type_info->stretch = UltraCondensedStretch;
367 else if (LocaleCompare(token,"UltraExpanded") == 0)
369 type_info->stretch = UltraExpandedStretch;
378 (void) CopyMagickString(buffer,value_name,family_extent-value_name+1);
380 type_info->family=ConstantString(buffer);
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);
389 RegCloseKey ( reg_key );