2 * Copyright (c) 2007-2010 SlimDX Group
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 #include "DirectWriteException.h"
26 #include "../direct2d/Matrix3x2.h"
27 #include "../stack_array.h"
29 #include "FactoryDW.h"
30 #include "FontCollection.h"
33 #include "GdiInterop.h"
34 #include "GlyphRunDW.h"
35 #include "GlyphRunAnalysis.h"
36 #include "IFontCollectionLoader.h"
37 #include "IFontFileLoader.h"
38 #include "InlineObject.h"
39 #include "NumberSubstitution.h"
40 #include "RenderingParameters.h"
41 #include "TextAnalyzer.h"
42 #include "TextFormat.h"
43 #include "TextLayout.h"
45 const IID IID_IDWriteFactory = __uuidof(IDWriteFactory);
47 using namespace System;
48 using namespace System::Runtime::InteropServices;
56 Init( FactoryType::Shared );
59 Factory::Factory( FactoryType factoryType )
64 void Factory::Init( FactoryType factoryType )
66 IDWriteFactory *factory = NULL;
68 if( RECORD_DW( DWriteCreateFactory( static_cast<DWRITE_FACTORY_TYPE>( factoryType ), IID_IDWriteFactory, reinterpret_cast<IUnknown**>( &factory ) ) ).IsFailure )
69 throw gcnew DirectWriteException( Result::Last );
74 FontCollection ^Factory::GetSystemFontCollection(bool checkForUpdates)
76 IDWriteFontCollection *collection = 0;
77 if (RECORD_DW(InternalPointer->GetSystemFontCollection(&collection, checkForUpdates ? TRUE : FALSE)).IsFailure)
81 return FontCollection::FromPointer(collection);
84 FontCollection ^Factory::CreateCustomFontCollection(IFontCollectionLoader ^loader, IntPtr collectionKey, int collectionKeySize)
86 IDWriteFontCollection *collection = 0;
87 IFontCollectionLoaderShim *shim = IFontCollectionLoaderShim::CreateInstance(loader);
88 if (RECORD_DW(InternalPointer->CreateCustomFontCollection(shim, collectionKey.ToPointer(), collectionKeySize, &collection)).IsFailure)
93 return FontCollection::FromPointer(collection);
96 FontFile ^Factory::CreateCustomFontFileReference(IntPtr fontFileReferenceKey, int fontFileReferenceKeySize, IFontFileLoader ^loader)
98 IDWriteFontFile *file = 0;
99 IFontFileLoaderShim *shim = IFontFileLoaderShim::CreateInstance(loader);
100 if (RECORD_DW(InternalPointer->CreateCustomFontFileReference(fontFileReferenceKey.ToPointer(), fontFileReferenceKeySize, shim, &file)).IsFailure)
105 return FontFile::FromPointer(file);
108 RenderingParameters ^Factory::CreateCustomRenderingParameters(
109 float gamma, float enhancedContrast, float clearTypeLevel,
110 PixelGeometry pixelGeometry, RenderingMode renderingMode)
112 IDWriteRenderingParams *params = 0;
113 if (RECORD_DW(InternalPointer->CreateCustomRenderingParams(gamma, enhancedContrast, clearTypeLevel,
114 static_cast<DWRITE_PIXEL_GEOMETRY>(pixelGeometry),
115 static_cast<DWRITE_RENDERING_MODE>(renderingMode), ¶ms)).IsFailure)
119 return RenderingParameters::FromPointer(params);
122 static TextLayout ^CreateGdiCompatibleTextLayoutInternal(IDWriteFactory *factory,
123 String ^text, TextFormat ^textFormat,
124 float layoutWidth, float layoutHeight, float pixelsPerDip,
125 DWRITE_MATRIX *transform, bool useGdiNatural)
127 pin_ptr<const wchar_t> pinnedText = PtrToStringChars(text);
129 IDWriteTextLayout *layout = 0;
130 if (RECORD_DW(factory->CreateGdiCompatibleTextLayout(pinnedText, text->Length,
131 textFormat->InternalPointer, layoutWidth, layoutHeight, pixelsPerDip,
132 transform, useGdiNatural ? TRUE : FALSE, &layout)).IsFailure)
136 return TextLayout::FromPointer(layout);
139 TextLayout ^Factory::CreateGdiCompatibleTextLayout(String ^text, TextFormat ^textFormat,
140 float layoutWidth, float layoutHeight, float pixelsPerDip, bool useGdiNatural)
142 return CreateGdiCompatibleTextLayoutInternal(InternalPointer, text, textFormat,
143 layoutWidth, layoutHeight, pixelsPerDip, 0, useGdiNatural);
145 TextLayout ^Factory::CreateGdiCompatibleTextLayout(String ^text, TextFormat ^textFormat,
146 float layoutWidth, float layoutHeight, float pixelsPerDip,
147 SlimDX::Direct2D::Matrix3x2 transform, bool useGdiNatural)
149 return CreateGdiCompatibleTextLayoutInternal(InternalPointer, text, textFormat,
150 layoutWidth, layoutHeight, pixelsPerDip,
151 reinterpret_cast<DWRITE_MATRIX *>(&transform), useGdiNatural);
153 InlineObject ^Factory::CreateEllipsisTrimmingSign(TextFormat ^textFormat)
155 IDWriteInlineObject *obj = 0;
156 if (RECORD_DW(InternalPointer->
157 CreateEllipsisTrimmingSign(textFormat->InternalPointer, &obj)).IsFailure)
161 return InlineObject::FromPointer(obj);
163 FontFace ^Factory::CreateFontFace(FontFaceType fontFaceType, array<FontFile^> ^fontFiles, int faceIndex, FontSimulations fontFaceSimulationFlags)
165 std::vector<IDWriteFontFile *> nativeFontFiles;
166 nativeFontFiles.resize(fontFiles->Length);
167 for (int i = 0; i < fontFiles->Length; i++)
169 nativeFontFiles[i] = fontFiles[i]->InternalPointer;
171 IDWriteFontFace *fontFace;
172 if (RECORD_DW(InternalPointer->CreateFontFace(static_cast<DWRITE_FONT_FACE_TYPE>(fontFaceType),
173 static_cast<UINT32>(nativeFontFiles.size()), &nativeFontFiles[0],
174 faceIndex, static_cast<DWRITE_FONT_SIMULATIONS>(fontFaceSimulationFlags),
175 &fontFace)).IsFailure)
179 return FontFace::FromPointer(fontFace);
182 static FontFile ^CreateFontFileReferenceInternal(IDWriteFactory *factory, String ^filePath, ::FILETIME const *fileTime)
184 pin_ptr<const wchar_t> pinnedText = PtrToStringChars(filePath);
186 IDWriteFontFile *fontFile = 0;
187 if (RECORD_DW(factory->CreateFontFileReference(pinnedText, fileTime, &fontFile)).IsFailure)
190 return FontFile::FromPointer(fontFile);
193 FontFile ^Factory::CreateFontFileReference(String ^filePath)
195 return CreateFontFileReferenceInternal(InternalPointer, filePath, 0);
197 FontFile ^Factory::CreateFontFileReference(String ^filePath, ComTypes::FILETIME fileTime)
199 return CreateFontFileReferenceInternal(InternalPointer, filePath, reinterpret_cast<::FILETIME *>(&fileTime));
202 static GlyphRunAnalysis ^CreateGlyphRunAnalysisInternal(IDWriteFactory *factory,
203 GlyphRun ^glyphRun, float pixelsPerDip, DWRITE_MATRIX *transform,
204 RenderingMode renderingMode, MeasuringMode measuringMode,
205 float baselineOriginX, float baselineOriginY)
207 stack_array<UINT16> indices;
208 stack_array<FLOAT> advances;
209 stack_array<DWRITE_GLYPH_OFFSET> offsets;
210 DWRITE_GLYPH_RUN nativeGlyphRun = glyphRun->ToUnmanaged(indices, advances, offsets);
211 IDWriteGlyphRunAnalysis *analysis = 0;
212 if (RECORD_DW(factory->CreateGlyphRunAnalysis(&nativeGlyphRun,
213 pixelsPerDip, transform,
214 static_cast<DWRITE_RENDERING_MODE>(renderingMode),
215 static_cast<DWRITE_MEASURING_MODE>(measuringMode),
216 baselineOriginX, baselineOriginY, &analysis)).IsFailure)
220 return GlyphRunAnalysis::FromPointer(analysis);
223 GlyphRunAnalysis ^Factory::CreateGlyphRunAnalysis(GlyphRun ^glyphRun, float pixelsPerDip,
224 RenderingMode renderingMode, MeasuringMode measuringMode,
225 float baselineOriginX, float baselineOriginY)
227 return CreateGlyphRunAnalysisInternal(InternalPointer,
228 glyphRun, pixelsPerDip, 0, renderingMode, measuringMode,
229 baselineOriginX, baselineOriginY);
231 GlyphRunAnalysis ^Factory::CreateGlyphRunAnalysis(GlyphRun ^glyphRun,
232 float pixelsPerDip, Matrix3x2 transform,
233 RenderingMode renderingMode, MeasuringMode measuringMode,
234 float baselineOriginX, float baselineOriginY)
236 return CreateGlyphRunAnalysisInternal(InternalPointer,
237 glyphRun, pixelsPerDip, reinterpret_cast<DWRITE_MATRIX *>(&transform),
238 renderingMode, measuringMode,
239 baselineOriginX, baselineOriginY);
242 RenderingParameters ^Factory::CreateMonitorRenderingParameters(IntPtr monitor)
244 IDWriteRenderingParams *params = 0;
245 if (RECORD_DW(InternalPointer->CreateMonitorRenderingParams(static_cast<HMONITOR>(monitor.ToPointer()), ¶ms)).IsFailure)
249 return RenderingParameters::FromPointer(params);
252 NumberSubstitution ^Factory::CreateNumberSubstitution(NumberSubstitutionMethod method, String ^localeName, bool ignoreUserOverride)
254 pin_ptr<const wchar_t> pinnedText = PtrToStringChars(localeName);
256 IDWriteNumberSubstitution *sub = 0;
257 if (RECORD_DW(InternalPointer->CreateNumberSubstitution(
258 static_cast<DWRITE_NUMBER_SUBSTITUTION_METHOD>(method), pinnedText,
259 ignoreUserOverride ? TRUE : FALSE, &sub)).IsFailure)
263 return NumberSubstitution::FromPointer(sub);
266 RenderingParameters ^Factory::CreateRenderingParameters()
268 IDWriteRenderingParams *params = 0;
269 if (RECORD_DW(InternalPointer->CreateRenderingParams(¶ms)).IsFailure)
273 return RenderingParameters::FromPointer(params);
276 TextAnalyzer ^Factory::CreateTextAnalyzer()
278 IDWriteTextAnalyzer *analyzer = 0;
279 if (RECORD_DW(InternalPointer->CreateTextAnalyzer(&analyzer)).IsFailure)
283 return TextAnalyzer::FromPointer(analyzer);
286 static TextFormat ^CreateTextFormatInternal(IDWriteFactory *factory,
287 String ^fontFamilyName, IDWriteFontCollection *fontCollection,
288 FontWeight fontWeight, FontStyle fontStyle, FontStretch fontStretch, float fontSize, String ^localeName)
290 pin_ptr<const wchar_t> pinnedText = PtrToStringChars(localeName);
291 pin_ptr<const wchar_t> pinnedName = PtrToStringChars(fontFamilyName);
293 IDWriteTextFormat *format = 0;
294 if (RECORD_DW(factory->CreateTextFormat(pinnedName,
295 fontCollection, static_cast<DWRITE_FONT_WEIGHT>(fontWeight),
296 static_cast<DWRITE_FONT_STYLE>(fontStyle),
297 static_cast<DWRITE_FONT_STRETCH>(fontStretch),
298 fontSize, pinnedText, &format)).IsFailure)
302 return TextFormat::FromPointer(format);
305 TextFormat ^Factory::CreateTextFormat(String ^fontFamilyName,
306 FontWeight fontWeight, FontStyle fontStyle, FontStretch fontStretch,
307 float fontSize, String ^localeName)
309 return CreateTextFormatInternal(InternalPointer, fontFamilyName, 0,
310 fontWeight, fontStyle, fontStretch, fontSize, localeName);
313 TextFormat ^Factory::CreateTextFormat(String ^fontFamilyName, FontCollection ^fontCollection,
314 FontWeight fontWeight, FontStyle fontStyle, FontStretch fontStretch,
315 float fontSize, String ^localeName)
317 return CreateTextFormatInternal(InternalPointer, fontFamilyName,
318 fontCollection->InternalPointer,
319 fontWeight, fontStyle, fontStretch, fontSize, localeName);
322 TextLayout ^Factory::CreateTextLayout(String ^text, TextFormat ^textFormat, float maxWidth, float maxHeight)
324 pin_ptr<const wchar_t> pinnedText = PtrToStringChars(text);
326 IDWriteTextLayout *layout = 0;
327 if (RECORD_DW(InternalPointer->CreateTextLayout(pinnedText, text->Length,
328 textFormat->InternalPointer, maxWidth, maxHeight, &layout)).IsFailure)
332 return TextLayout::FromPointer(layout);
335 Typography ^Factory::CreateTypography()
337 IDWriteTypography *typography;
338 if (RECORD_DW(InternalPointer->CreateTypography(&typography)).IsFailure)
342 return Typography::FromPointer(typography);
345 GdiInterop ^Factory::GetGdiInterop()
347 IDWriteGdiInterop *gdiInterop;
348 if (RECORD_DW(InternalPointer->GetGdiInterop(&gdiInterop)).IsFailure)
352 return GdiInterop::FromPointer(gdiInterop);
355 Result Factory::RegisterFontCollectionLoader(IFontCollectionLoader ^loader)
357 IFontCollectionLoaderShim *shim = IFontCollectionLoaderShim::CreateInstance(loader);
358 return RECORD_DW(InternalPointer->RegisterFontCollectionLoader(shim));
361 Result Factory::RegisterFontFileLoader(IFontFileLoader ^loader)
363 IFontFileLoaderShim *shim = IFontFileLoaderShim::CreateInstance(loader);
364 return RECORD_DW(InternalPointer->RegisterFontFileLoader(shim));
367 Result Factory::UnregisterFontCollectionLoader(IFontCollectionLoader ^loader)
369 IFontCollectionLoaderShim *shim = IFontCollectionLoaderShim::CreateInstance(loader);
370 return RECORD_DW(InternalPointer->UnregisterFontCollectionLoader(shim));
373 Result Factory::UnregisterFontFileLoader(IFontFileLoader ^loader)
375 IFontFileLoaderShim *shim = IFontFileLoaderShim::CreateInstance(loader);
376 return RECORD_DW(InternalPointer->UnregisterFontFileLoader(shim));