StringArray Font::findAllTypefaceFamilies() { StringArray results; #if JUCE_USE_DIRECTWRITE const Direct2DFactories& factories = Direct2DFactories::getInstance(); if (factories.systemFonts != nullptr) { ComSmartPtr<IDWriteFontFamily> dwFontFamily; uint32 fontFamilyCount = 0; fontFamilyCount = factories.systemFonts->GetFontFamilyCount(); for (uint32 i = 0; i < fontFamilyCount; ++i) { HRESULT hr = factories.systemFonts->GetFontFamily (i, dwFontFamily.resetAndGetPointerAddress()); ComSmartPtr<IDWriteLocalizedStrings> dwFamilyNames; hr = dwFontFamily->GetFamilyNames (dwFamilyNames.resetAndGetPointerAddress()); jassert (dwFamilyNames != nullptr); uint32 index = 0; BOOL exists = false; hr = dwFamilyNames->FindLocaleName (L"en-us", &index, &exists); if (! exists) index = 0; uint32 length = 0; hr = dwFamilyNames->GetStringLength (index, &length); HeapBlock <wchar_t> familyName (length + 1); hr = dwFamilyNames->GetString (index, familyName, length + 1); results.add(String (familyName)); } } else #endif { HDC dc = CreateCompatibleDC (0); { LOGFONTW lf = { 0 }; lf.lfWeight = FW_DONTCARE; lf.lfOutPrecision = OUT_OUTLINE_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfCharSet = DEFAULT_CHARSET; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfPitchAndFamily = FF_DONTCARE; EnumFontFamiliesEx (dc, &lf, (FONTENUMPROCW) &FontEnumerators::fontEnum1, (LPARAM) &results, 0); } DeleteDC (dc); } results.sort (true); return results; }
bool isRendererConnected() { ComSmartPtr <IEnumPins> enumPins; HRESULT hr = baseFilter->EnumPins (enumPins.resetAndGetPointerAddress()); if (SUCCEEDED (hr)) hr = enumPins->Reset(); ComSmartPtr<IPin> pin; while (SUCCEEDED (hr) && enumPins->Next (1, pin.resetAndGetPointerAddress(), nullptr) == S_OK) { ComSmartPtr<IPin> otherPin; hr = pin->ConnectedTo (otherPin.resetAndGetPointerAddress()); if (SUCCEEDED (hr)) { PIN_DIRECTION direction; hr = pin->QueryDirection (&direction); if (SUCCEEDED (hr) && direction == PINDIR_INPUT) return true; } else if (hr == VFW_E_NOT_CONNECTED) { hr = S_OK; } } return false; }
void addAttributedRange (const AttributedString::Attribute& attr, IDWriteTextLayout* textLayout, const int textLen, ID2D1RenderTarget* const renderTarget, IDWriteFontCollection* const fontCollection) { DWRITE_TEXT_RANGE range; range.startPosition = attr.range.getStart(); range.length = jmin (attr.range.getLength(), textLen - attr.range.getStart()); const Font* const font = attr.getFont(); if (font != nullptr) { BOOL fontFound = false; uint32 fontIndex; fontCollection->FindFamilyName (FontStyleHelpers::getConcreteFamilyName (*font).toWideCharPointer(), &fontIndex, &fontFound); if (! fontFound) fontIndex = 0; ComSmartPtr<IDWriteFontFamily> fontFamily; HRESULT hr = fontCollection->GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress()); ComSmartPtr<IDWriteFont> dwFont; uint32 fontFacesCount = 0; fontFacesCount = fontFamily->GetFontCount(); for (int i = fontFacesCount; --i >= 0;) { hr = fontFamily->GetFont (i, dwFont.resetAndGetPointerAddress()); if (font->getTypefaceStyle() == getFontFaceName (dwFont)) break; } textLayout->SetFontFamilyName (attr.getFont()->getTypefaceName().toWideCharPointer(), range); textLayout->SetFontWeight (dwFont->GetWeight(), range); textLayout->SetFontStretch (dwFont->GetStretch(), range); textLayout->SetFontStyle (dwFont->GetStyle(), range); const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (dwFont); textLayout->SetFontSize (font->getHeight() * fontHeightToEmSizeFactor, range); } if (attr.getColour() != nullptr) { ComSmartPtr<ID2D1SolidColorBrush> d2dBrush; renderTarget->CreateSolidColorBrush (D2D1::ColorF (D2D1::ColorF (attr.getColour()->getFloatRed(), attr.getColour()->getFloatGreen(), attr.getColour()->getFloatBlue(), attr.getColour()->getFloatAlpha())), d2dBrush.resetAndGetPointerAddress()); // We need to call SetDrawingEffect with a legimate brush to get DirectWrite to break text based on colours textLayout->SetDrawingEffect (d2dBrush, range); } }
bool setupLayout (const AttributedString& text, const float maxWidth, const float maxHeight, ID2D1RenderTarget& renderTarget, IDWriteFactory& directWriteFactory, IDWriteFontCollection& fontCollection, ComSmartPtr<IDWriteTextLayout>& textLayout) { // To add color to text, we need to create a D2D render target // Since we are not actually rendering to a D2D context we create a temporary GDI render target Font defaultFont; BOOL fontFound = false; uint32 fontIndex; fontCollection.FindFamilyName (defaultFont.getTypeface()->getName().toWideCharPointer(), &fontIndex, &fontFound); if (! fontFound) fontIndex = 0; ComSmartPtr<IDWriteFontFamily> dwFontFamily; HRESULT hr = fontCollection.GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress()); ComSmartPtr<IDWriteFont> dwFont; hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, dwFont.resetAndGetPointerAddress()); jassert (dwFont != nullptr); const float defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont); ComSmartPtr<IDWriteTextFormat> dwTextFormat; hr = directWriteFactory.CreateTextFormat (defaultFont.getTypefaceName().toWideCharPointer(), &fontCollection, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, defaultFont.getHeight() * defaultFontHeightToEmSizeFactor, L"en-us", dwTextFormat.resetAndGetPointerAddress()); setTextFormatProperties (text, *dwTextFormat); { DWRITE_TRIMMING trimming = { DWRITE_TRIMMING_GRANULARITY_CHARACTER, 0, 0 }; ComSmartPtr<IDWriteInlineObject> trimmingSign; hr = directWriteFactory.CreateEllipsisTrimmingSign (dwTextFormat, trimmingSign.resetAndGetPointerAddress()); hr = dwTextFormat->SetTrimming (&trimming, trimmingSign); } const int textLen = text.getText().length(); hr = directWriteFactory.CreateTextLayout (text.getText().toWideCharPointer(), textLen, dwTextFormat, maxWidth, maxHeight, textLayout.resetAndGetPointerAddress()); if (FAILED (hr) || textLayout == nullptr) return false; const int numAttributes = text.getNumAttributes(); for (int i = 0; i < numAttributes; ++i) addAttributedRange (*text.getAttribute (i), *textLayout, textLen, renderTarget, fontCollection); return true; }
void getFontFamilyAndStyle (DWRITE_GLYPH_RUN const* glyphRun, String& family, String& style) const { ComSmartPtr<IDWriteFont> dwFont; HRESULT hr = fontCollection->GetFontFromFontFace (glyphRun->fontFace, dwFont.resetAndGetPointerAddress()); jassert (dwFont != nullptr); { ComSmartPtr<IDWriteFontFamily> dwFontFamily; hr = dwFont->GetFontFamily (dwFontFamily.resetAndGetPointerAddress()); family = getFontFamilyName (dwFontFamily); } style = getFontFaceName (dwFont); }
StringArray Font::findAllTypefaceStyles (const String& family) { if (FontStyleHelpers::isPlaceholderFamilyName (family)) return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family)); StringArray results; #if JUCE_USE_DIRECTWRITE const Direct2DFactories& factories = Direct2DFactories::getInstance(); if (factories.systemFonts != nullptr) { BOOL fontFound = false; uint32 fontIndex = 0; HRESULT hr = factories.systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound); if (! fontFound) fontIndex = 0; // Get the font family using the search results // Fonts like: Times New Roman, Times New Roman Bold, Times New Roman Italic are all in the same font family ComSmartPtr<IDWriteFontFamily> fontFamily; hr = factories.systemFonts->GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress()); // Get the font faces ComSmartPtr<IDWriteFont> dwFont; uint32 fontFacesCount = 0; fontFacesCount = fontFamily->GetFontCount(); for (uint32 i = 0; i < fontFacesCount; ++i) { hr = fontFamily->GetFont (i, dwFont.resetAndGetPointerAddress()); // Ignore any algorithmically generated bold and oblique styles.. if (dwFont->GetSimulations() == DWRITE_FONT_SIMULATIONS_NONE) results.addIfNotAlreadyThere (getFontFaceName (dwFont)); } } else #endif { results.add ("Regular"); results.add ("Italic"); results.add ("Bold"); results.add ("Bold Italic"); } return results; }
Font getFontForRun (const DWRITE_GLYPH_RUN& glyphRun, float fontHeight) { for (int i = 0; i < attributedString.getNumAttributes(); ++i) if (const Font* font = attributedString.getAttribute(i)->getFont()) if (WindowsDirectWriteTypeface* wt = dynamic_cast<WindowsDirectWriteTypeface*> (font->getTypeface())) if (wt->getIDWriteFontFace() == glyphRun.fontFace) return font->withHeight (fontHeight); ComSmartPtr<IDWriteFont> dwFont; HRESULT hr = fontCollection.GetFontFromFontFace (glyphRun.fontFace, dwFont.resetAndGetPointerAddress()); jassert (dwFont != nullptr); ComSmartPtr<IDWriteFontFamily> dwFontFamily; hr = dwFont->GetFontFamily (dwFontFamily.resetAndGetPointerAddress()); return Font (getFontFamilyName (dwFontFamily), getFontFaceName (dwFont), fontHeight); }
void setupLayout (const AttributedString& text, const float& maxWidth, const float& maxHeight, ID2D1RenderTarget* const renderTarget, IDWriteFactory* const directWriteFactory, IDWriteFontCollection* const fontCollection, IDWriteTextLayout** dwTextLayout) { // To add color to text, we need to create a D2D render target // Since we are not actually rendering to a D2D context we create a temporary GDI render target Font defaultFont; BOOL fontFound = false; uint32 fontIndex; fontCollection->FindFamilyName (defaultFont.getTypeface()->getName().toWideCharPointer(), &fontIndex, &fontFound); if (! fontFound) fontIndex = 0; ComSmartPtr<IDWriteFontFamily> dwFontFamily; HRESULT hr = fontCollection->GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress()); ComSmartPtr<IDWriteFont> dwFont; hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, dwFont.resetAndGetPointerAddress()); const float defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (dwFont); jassert (directWriteFactory != nullptr); ComSmartPtr<IDWriteTextFormat> dwTextFormat; hr = directWriteFactory->CreateTextFormat (defaultFont.getTypefaceName().toWideCharPointer(), fontCollection, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, defaultFont.getHeight() * defaultFontHeightToEmSizeFactor, L"en-us", dwTextFormat.resetAndGetPointerAddress()); setTextFormatProperties (text, dwTextFormat); const int textLen = text.getText().length(); hr = directWriteFactory->CreateTextLayout (text.getText().toWideCharPointer(), textLen, dwTextFormat, maxWidth, maxHeight, dwTextLayout); const int numAttributes = text.getNumAttributes(); for (int i = 0; i < numAttributes; ++i) addAttributedRange (*text.getAttribute (i), *dwTextLayout, textLen, renderTarget, fontCollection); }
//================================================================================================== float getFontHeightToEmSizeFactor (IDWriteFont* const dwFont) { ComSmartPtr<IDWriteFontFace> dwFontFace; dwFont->CreateFontFace (dwFontFace.resetAndGetPointerAddress()); DWRITE_FONT_METRICS dwFontMetrics; dwFontFace->GetMetrics (&dwFontMetrics); const float totalHeight = (float) (std::abs (dwFontMetrics.ascent) + std::abs (dwFontMetrics.descent)); return dwFontMetrics.designUnitsPerEm / totalHeight; }
int getIntProperty (const LPOLESTR name, const int defaultReturn) const { ComSmartPtr<IPropertyStorage> prop; if (FAILED (discRecorder->GetRecorderProperties (prop.resetAndGetPointerAddress()))) return defaultReturn; PROPSPEC iPropSpec; iPropSpec.ulKind = PRSPEC_LPWSTR; iPropSpec.lpwstr = name; PROPVARIANT iPropVariant; return FAILED (prop->ReadMultiple (1, &iPropSpec, &iPropVariant)) ? defaultReturn : (int) iPropVariant.lVal; }
void scanFileForDetails() { ComSmartPtr<IWMHeaderInfo> wmHeaderInfo; HRESULT hr = wmSyncReader.QueryInterface (wmHeaderInfo); if (SUCCEEDED (hr)) { QWORD lengthInNanoseconds = 0; WORD lengthOfLength = sizeof (lengthInNanoseconds); WORD streamNum = 0; WMT_ATTR_DATATYPE wmAttrDataType; hr = wmHeaderInfo->GetAttributeByName (&streamNum, L"Duration", &wmAttrDataType, (BYTE*) &lengthInNanoseconds, &lengthOfLength); ComSmartPtr<IWMProfile> wmProfile; hr = wmSyncReader.QueryInterface (wmProfile); if (SUCCEEDED (hr)) { ComSmartPtr<IWMStreamConfig> wmStreamConfig; hr = wmProfile->GetStream (0, wmStreamConfig.resetAndGetPointerAddress()); if (SUCCEEDED (hr)) { ComSmartPtr<IWMMediaProps> wmMediaProperties; hr = wmStreamConfig.QueryInterface (wmMediaProperties); if (SUCCEEDED (hr)) { DWORD sizeMediaType; hr = wmMediaProperties->GetMediaType (0, &sizeMediaType); HeapBlock<WM_MEDIA_TYPE> mediaType; mediaType.malloc (sizeMediaType, 1); hr = wmMediaProperties->GetMediaType (mediaType, &sizeMediaType); if (mediaType->majortype == WMMEDIATYPE_Audio) { const WAVEFORMATEX* const inputFormat = reinterpret_cast<WAVEFORMATEX*> (mediaType->pbFormat); sampleRate = inputFormat->nSamplesPerSec; numChannels = inputFormat->nChannels; bitsPerSample = inputFormat->wBitsPerSample; lengthInSamples = (lengthInNanoseconds * (int) sampleRate) / 10000000; } } } } } }
void drawToD2DContext (const AttributedString& text, const Rectangle<float>& area, ID2D1RenderTarget* const renderTarget, IDWriteFactory* const directWriteFactory, IDWriteFontCollection* const fontCollection) { ComSmartPtr<IDWriteTextLayout> dwTextLayout; setupLayout (text, area.getWidth(), area.getHeight(), renderTarget, directWriteFactory, fontCollection, dwTextLayout.resetAndGetPointerAddress()); ComSmartPtr<ID2D1SolidColorBrush> d2dBrush; renderTarget->CreateSolidColorBrush (D2D1::ColorF (D2D1::ColorF (0.0f, 0.0f, 0.0f, 1.0f)), d2dBrush.resetAndGetPointerAddress()); renderTarget->DrawTextLayout (D2D1::Point2F ((float) area.getX(), (float) area.getY()), dwTextLayout, d2dBrush, D2D1_DRAW_TEXT_OPTIONS_CLIP); }
ID2D1PathGeometry* Direct2DLowLevelGraphicsContext::pathToPathGeometry (const Path& path, const AffineTransform& transform) { ID2D1PathGeometry* p = nullptr; Direct2DFactories::getInstance().d2dFactory->CreatePathGeometry (&p); ComSmartPtr <ID2D1GeometrySink> sink; HRESULT hr = p->Open (sink.resetAndGetPointerAddress()); sink->SetFillMode (D2D1_FILL_MODE_WINDING); // xxx need to check Path::isUsingNonZeroWinding() pathToGeometrySink (path, sink, transform); hr = sink->Close(); return p; }
ID2D1PathGeometry* Direct2DLowLevelGraphicsContext::rectListToPathGeometry (const RectangleList& clipRegion) { ID2D1PathGeometry* p = nullptr; Direct2DFactories::getInstance().d2dFactory->CreatePathGeometry (&p); ComSmartPtr <ID2D1GeometrySink> sink; HRESULT hr = p->Open (sink.resetAndGetPointerAddress()); // xxx handle error sink->SetFillMode (D2D1_FILL_MODE_WINDING); for (int i = clipRegion.getNumRectangles(); --i >= 0;) rectToGeometrySink (clipRegion.getRectangle(i), sink); hr = sink->Close(); return p; }
void createLayout (TextLayout& layout, const AttributedString& text, IDWriteFactory& directWriteFactory, ID2D1Factory& direct2dFactory, IDWriteFontCollection& fontCollection) { // To add color to text, we need to create a D2D render target // Since we are not actually rendering to a D2D context we create a temporary GDI render target D2D1_RENDER_TARGET_PROPERTIES d2dRTProp = D2D1::RenderTargetProperties (D2D1_RENDER_TARGET_TYPE_SOFTWARE, D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), 0, 0, D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, D2D1_FEATURE_LEVEL_DEFAULT); ComSmartPtr<ID2D1DCRenderTarget> renderTarget; HRESULT hr = direct2dFactory.CreateDCRenderTarget (&d2dRTProp, renderTarget.resetAndGetPointerAddress()); ComSmartPtr<IDWriteTextLayout> dwTextLayout; if (! setupLayout (text, layout.getWidth(), layout.getHeight(), *renderTarget, directWriteFactory, fontCollection, dwTextLayout)) return; UINT32 actualLineCount = 0; hr = dwTextLayout->GetLineMetrics (nullptr, 0, &actualLineCount); layout.ensureStorageAllocated (actualLineCount); { ComSmartPtr<CustomDirectWriteTextRenderer> textRenderer (new CustomDirectWriteTextRenderer (fontCollection, text)); hr = dwTextLayout->Draw (&layout, textRenderer, 0, 0); } HeapBlock<DWRITE_LINE_METRICS> dwLineMetrics (actualLineCount); hr = dwTextLayout->GetLineMetrics (dwLineMetrics, actualLineCount, &actualLineCount); int lastLocation = 0; const int numLines = jmin ((int) actualLineCount, layout.getNumLines()); float yAdjustment = 0; const float extraLineSpacing = text.getLineSpacing(); for (int i = 0; i < numLines; ++i) { TextLayout::Line& line = layout.getLine (i); line.stringRange = Range<int> (lastLocation, (int) lastLocation + dwLineMetrics[i].length); line.lineOrigin.y += yAdjustment; yAdjustment += extraLineSpacing; lastLocation += dwLineMetrics[i].length; } }
StringArray Font::findAllTypefaceNames() { StringArray results; #if JUCE_USE_DIRECTWRITE const Direct2DFactories& factories = Direct2DFactories::getInstance(); if (factories.systemFonts != nullptr) { ComSmartPtr<IDWriteFontFamily> fontFamily; uint32 fontFamilyCount = 0; fontFamilyCount = factories.systemFonts->GetFontFamilyCount(); for (uint32 i = 0; i < fontFamilyCount; ++i) { HRESULT hr = factories.systemFonts->GetFontFamily (i, fontFamily.resetAndGetPointerAddress()); if (SUCCEEDED (hr)) results.addIfNotAlreadyThere (getFontFamilyName (fontFamily)); } } else #endif { HDC dc = CreateCompatibleDC (0); { LOGFONTW lf = { 0 }; lf.lfWeight = FW_DONTCARE; lf.lfOutPrecision = OUT_OUTLINE_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfCharSet = DEFAULT_CHARSET; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfPitchAndFamily = FF_DONTCARE; EnumFontFamiliesEx (dc, &lf, (FONTENUMPROCW) &FontEnumerators::fontEnum1, (LPARAM) &results, 0); } DeleteDC (dc); } results.sort (true); return results; }
bool setIntProperty (const LPOLESTR name, const int value) const { ComSmartPtr<IPropertyStorage> prop; if (FAILED (discRecorder->GetRecorderProperties (prop.resetAndGetPointerAddress()))) return false; PROPSPEC iPropSpec; iPropSpec.ulKind = PRSPEC_LPWSTR; iPropSpec.lpwstr = name; PROPVARIANT iPropVariant; if (FAILED (prop->ReadMultiple (1, &iPropSpec, &iPropVariant))) return false; iPropVariant.lVal = (long) value; return SUCCEEDED (prop->WriteMultiple (1, &iPropSpec, &iPropVariant, iPropVariant.vt)) && SUCCEEDED (discRecorder->SetRecorderProperties (prop)); }
void Direct2DLowLevelGraphicsContext::drawImage (const Image& image, const AffineTransform& transform) { renderingTarget->SetTransform (transformToMatrix (transform.followedBy (currentState->transform))); D2D1_SIZE_U size; size.width = image.getWidth(); size.height = image.getHeight(); D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); Image img (image.convertedToFormat (Image::ARGB)); Image::BitmapData bd (img, Image::BitmapData::readOnly); bp.pixelFormat = renderingTarget->GetPixelFormat(); bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; { ComSmartPtr <ID2D1Bitmap> tempBitmap; renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, tempBitmap.resetAndGetPointerAddress()); if (tempBitmap != nullptr) renderingTarget->DrawBitmap (tempBitmap); } }
void createLayout (TextLayout& layout, const AttributedString& text, IDWriteFactory* const directWriteFactory, ID2D1Factory* const direct2dFactory, IDWriteFontCollection* const fontCollection) { // To add color to text, we need to create a D2D render target // Since we are not actually rendering to a D2D context we create a temporary GDI render target D2D1_RENDER_TARGET_PROPERTIES d2dRTProp = D2D1::RenderTargetProperties (D2D1_RENDER_TARGET_TYPE_SOFTWARE, D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), 0, 0, D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, D2D1_FEATURE_LEVEL_DEFAULT); ComSmartPtr<ID2D1DCRenderTarget> renderTarget; HRESULT hr = direct2dFactory->CreateDCRenderTarget (&d2dRTProp, renderTarget.resetAndGetPointerAddress()); Font defaultFont; BOOL fontFound = false; uint32 fontIndex; fontCollection->FindFamilyName (defaultFont.getTypefaceName().toWideCharPointer(), &fontIndex, &fontFound); if (! fontFound) fontIndex = 0; ComSmartPtr<IDWriteFontFamily> dwFontFamily; hr = fontCollection->GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress()); ComSmartPtr<IDWriteFont> dwFont; hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, dwFont.resetAndGetPointerAddress()); const float defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (dwFont); jassert (directWriteFactory != nullptr); ComSmartPtr<IDWriteTextFormat> dwTextFormat; hr = directWriteFactory->CreateTextFormat (defaultFont.getTypefaceName().toWideCharPointer(), fontCollection, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, defaultFont.getHeight() * defaultFontHeightToEmSizeFactor, L"en-us", dwTextFormat.resetAndGetPointerAddress()); setTextFormatProperties (text, dwTextFormat); const int textLen = text.getText().length(); ComSmartPtr<IDWriteTextLayout> dwTextLayout; hr = directWriteFactory->CreateTextLayout (text.getText().toWideCharPointer(), textLen, dwTextFormat, layout.getWidth(), 1.0e7f, dwTextLayout.resetAndGetPointerAddress()); const int numAttributes = text.getNumAttributes(); for (int i = 0; i < numAttributes; ++i) addAttributedRange (*text.getAttribute (i), dwTextLayout, textLen, renderTarget, fontCollection); UINT32 actualLineCount = 0; hr = dwTextLayout->GetLineMetrics (nullptr, 0, &actualLineCount); layout.ensureStorageAllocated (actualLineCount); { ComSmartPtr<CustomDirectWriteTextRenderer> textRenderer (new CustomDirectWriteTextRenderer (fontCollection)); hr = dwTextLayout->Draw (&layout, textRenderer, 0, 0); } HeapBlock <DWRITE_LINE_METRICS> dwLineMetrics (actualLineCount); hr = dwTextLayout->GetLineMetrics (dwLineMetrics, actualLineCount, &actualLineCount); int lastLocation = 0; const int numLines = jmin ((int) actualLineCount, layout.getNumLines()); for (int i = 0; i < numLines; ++i) { lastLocation = dwLineMetrics[i].length; layout.getLine(i).stringRange = Range<int> (lastLocation, (int) lastLocation + dwLineMetrics[i].length); } }
DShowCameraDeviceInteral (CameraDevice* const owner_, const ComSmartPtr <ICaptureGraphBuilder2>& captureGraphBuilder_, const ComSmartPtr <IBaseFilter>& filter_, int minWidth, int minHeight, int maxWidth, int maxHeight) : owner (owner_), captureGraphBuilder (captureGraphBuilder_), filter (filter_), ok (false), imageNeedsFlipping (false), width (0), height (0), activeUsers (0), recordNextFrameTime (false), previewMaxFPS (60) { HRESULT hr = graphBuilder.CoCreateInstance (CLSID_FilterGraph); if (FAILED (hr)) return; hr = captureGraphBuilder->SetFiltergraph (graphBuilder); if (FAILED (hr)) return; hr = graphBuilder.QueryInterface (mediaControl); if (FAILED (hr)) return; { ComSmartPtr <IAMStreamConfig> streamConfig; hr = captureGraphBuilder->FindInterface (&PIN_CATEGORY_CAPTURE, 0, filter, IID_IAMStreamConfig, (void**) streamConfig.resetAndGetPointerAddress()); if (streamConfig != nullptr) { getVideoSizes (streamConfig); if (! selectVideoSize (streamConfig, minWidth, minHeight, maxWidth, maxHeight)) return; } } hr = graphBuilder->AddFilter (filter, _T("Video Capture")); if (FAILED (hr)) return; hr = smartTee.CoCreateInstance (CLSID_SmartTee); if (FAILED (hr)) return; hr = graphBuilder->AddFilter (smartTee, _T("Smart Tee")); if (FAILED (hr)) return; if (! connectFilters (filter, smartTee)) return; ComSmartPtr <IBaseFilter> sampleGrabberBase; hr = sampleGrabberBase.CoCreateInstance (CLSID_SampleGrabber); if (FAILED (hr)) return; hr = sampleGrabberBase.QueryInterface (IID_ISampleGrabber, sampleGrabber); if (FAILED (hr)) return; { AM_MEDIA_TYPE mt = { 0 }; mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB24; mt.formattype = FORMAT_VideoInfo; sampleGrabber->SetMediaType (&mt); } callback = new GrabberCallback (*this); hr = sampleGrabber->SetCallback (callback, 1); hr = graphBuilder->AddFilter (sampleGrabberBase, _T("Sample Grabber")); if (FAILED (hr)) return; ComSmartPtr <IPin> grabberInputPin; if (! (getPin (smartTee, PINDIR_OUTPUT, smartTeeCaptureOutputPin, "capture") && getPin (smartTee, PINDIR_OUTPUT, smartTeePreviewOutputPin, "preview") && getPin (sampleGrabberBase, PINDIR_INPUT, grabberInputPin))) return; hr = graphBuilder->Connect (smartTeePreviewOutputPin, grabberInputPin); if (FAILED (hr)) return; AM_MEDIA_TYPE mt = { 0 }; hr = sampleGrabber->GetConnectedMediaType (&mt); VIDEOINFOHEADER* pVih = (VIDEOINFOHEADER*) (mt.pbFormat); width = pVih->bmiHeader.biWidth; height = pVih->bmiHeader.biHeight; ComSmartPtr <IBaseFilter> nullFilter; hr = nullFilter.CoCreateInstance (CLSID_NullRenderer); hr = graphBuilder->AddFilter (nullFilter, _T("Null Renderer")); if (connectFilters (sampleGrabberBase, nullFilter) && addGraphToRot()) { activeImage = Image (Image::RGB, width, height, true); loadingImage = Image (Image::RGB, width, height, true); ok = true; } }
bool createFileCaptureFilter (const File& file, int quality) { removeFileCaptureFilter(); file.deleteFile(); mediaControl->Stop(); firstRecordedTime = Time(); recordNextFrameTime = true; previewMaxFPS = 60; HRESULT hr = asfWriter.CoCreateInstance (CLSID_WMAsfWriter); if (SUCCEEDED (hr)) { ComSmartPtr <IFileSinkFilter> fileSink; hr = asfWriter.QueryInterface (fileSink); if (SUCCEEDED (hr)) { hr = fileSink->SetFileName (file.getFullPathName().toWideCharPointer(), 0); if (SUCCEEDED (hr)) { hr = graphBuilder->AddFilter (asfWriter, _T("AsfWriter")); if (SUCCEEDED (hr)) { ComSmartPtr <IConfigAsfWriter> asfConfig; hr = asfWriter.QueryInterface (asfConfig); asfConfig->SetIndexMode (true); ComSmartPtr <IWMProfileManager> profileManager; hr = WMCreateProfileManager (profileManager.resetAndGetPointerAddress()); // This gibberish is the DirectShow profile for a video-only wmv file. String prof ("<profile version=\"589824\" storageformat=\"1\" name=\"Quality\" description=\"Quality type for output.\">" "<streamconfig majortype=\"{73646976-0000-0010-8000-00AA00389B71}\" streamnumber=\"1\" " "streamname=\"Video Stream\" inputname=\"Video409\" bitrate=\"894960\" " "bufferwindow=\"0\" reliabletransport=\"1\" decodercomplexity=\"AU\" rfc1766langid=\"en-us\">" "<videomediaprops maxkeyframespacing=\"50000000\" quality=\"90\"/>" "<wmmediatype subtype=\"{33564D57-0000-0010-8000-00AA00389B71}\" bfixedsizesamples=\"0\" " "btemporalcompression=\"1\" lsamplesize=\"0\">" "<videoinfoheader dwbitrate=\"894960\" dwbiterrorrate=\"0\" avgtimeperframe=\"$AVGTIMEPERFRAME\">" "<rcsource left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/>" "<rctarget left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/>" "<bitmapinfoheader biwidth=\"$WIDTH\" biheight=\"$HEIGHT\" biplanes=\"1\" bibitcount=\"24\" " "bicompression=\"WMV3\" bisizeimage=\"0\" bixpelspermeter=\"0\" biypelspermeter=\"0\" " "biclrused=\"0\" biclrimportant=\"0\"/>" "</videoinfoheader>" "</wmmediatype>" "</streamconfig>" "</profile>"); const int fps[] = { 10, 15, 30 }; int maxFramesPerSecond = fps [jlimit (0, numElementsInArray (fps) - 1, quality & 0xff)]; if ((quality & 0xff000000) != 0) // (internal hacky way to pass explicit frame rates for testing) maxFramesPerSecond = (quality >> 24) & 0xff; prof = prof.replace ("$WIDTH", String (width)) .replace ("$HEIGHT", String (height)) .replace ("$AVGTIMEPERFRAME", String (10000000 / maxFramesPerSecond)); ComSmartPtr <IWMProfile> currentProfile; hr = profileManager->LoadProfileByData (prof.toWideCharPointer(), currentProfile.resetAndGetPointerAddress()); hr = asfConfig->ConfigureFilterUsingProfile (currentProfile); if (SUCCEEDED (hr)) { ComSmartPtr <IPin> asfWriterInputPin; if (getPin (asfWriter, PINDIR_INPUT, asfWriterInputPin, "Video Input 01")) { hr = graphBuilder->Connect (smartTeeCaptureOutputPin, asfWriterInputPin); if (SUCCEEDED (hr) && ok && activeUsers > 0 && SUCCEEDED (mediaControl->Run())) { previewMaxFPS = (quality < 2) ? 15 : 25; // throttle back the preview comps to try to leave the cpu free for encoding if ((quality & 0x00ff0000) != 0) // (internal hacky way to pass explicit frame rates for testing) previewMaxFPS = (quality >> 16) & 0xff; return true; } } } } } }
StringArray Font::findAllTypefaceStyles(const String& family) { StringArray results; #if JUCE_USE_DIRECTWRITE const Direct2DFactories& factories = Direct2DFactories::getInstance(); if (factories.systemFonts != nullptr) { BOOL fontFound = false; uint32 fontIndex = 0; HRESULT hr = factories.systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound); if (! fontFound) fontIndex = 0; // Get the font family using the search results // Fonts like: Times New Roman, Times New Roman Bold, Times New Roman Italic are all in the same font family ComSmartPtr<IDWriteFontFamily> dwFontFamily; hr = factories.systemFonts->GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress()); // Get the font faces ComSmartPtr<IDWriteFont> dwFont; uint32 fontFacesCount = 0; fontFacesCount = dwFontFamily->GetFontCount(); for (uint32 i = 0; i < fontFacesCount; ++i) { hr = dwFontFamily->GetFont (i, dwFont.resetAndGetPointerAddress()); ComSmartPtr<IDWriteLocalizedStrings> dwFaceNames; hr = dwFont->GetFaceNames (dwFaceNames.resetAndGetPointerAddress()); jassert (dwFaceNames != nullptr); uint32 index = 0; BOOL exists = false; hr = dwFaceNames->FindLocaleName (L"en-us", &index, &exists); if (! exists) index = 0; uint32 length = 0; hr = dwFaceNames->GetStringLength (index, &length); HeapBlock <wchar_t> styleName (length + 1); hr = dwFaceNames->GetString (index, styleName, length + 1); String style (styleName); // For unknown reasons, DirectWrite does not enumerate the Arial Narrow fonts properly. // It uses the same style name "Narrow" for all four fonts. Since only one of these fonts // is accessible, we will ignore the duplicates. if (style == "Narrow" && results.contains("Narrow")) continue; // DirectWrite automatically adds extra bold and oblique font styles which are algorithmic // style simulations. These styles don't show up in any other software. We will ignore them. if (dwFont->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) continue; results.add(style); } } else #endif { results.add ("Regular"); results.add ("Italic"); results.add ("Bold"); results.add ("Bold Italic"); } return results; }