精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

操作實例:閱讀器應(yīng)用(DirectX 和 XAML)

開發(fā) 前端
下面我們介紹如何使用 DirectX、C++ 和 XAML 創(chuàng)建豐富的文檔閱讀器應(yīng)用。我們涵蓋了此類型應(yīng)用的結(jié)構(gòu)、技術(shù)和最佳實踐,包括如何使用 Virtual Surface Image Source 在 DirectX 繪圖代碼和 XAML 界面管理之間進(jìn)行交互操作,使用 DirectWrite 加載字體,使用 WIC 加載圖像,以及將 Direct2D 圖像效果應(yīng)用到圖像。

隨著平板電腦變得越來越普及,融合了閱讀體驗的應(yīng)用很快就會變得流行起來。 下面我們介紹如何使用 DirectX、C++ 和 XAML 創(chuàng)建豐富的文檔閱讀器應(yīng)用。我們涵蓋了此類型應(yīng)用的結(jié)構(gòu)、技術(shù)和***實踐,包括如何使用 Virtual Surface Image Source 在 DirectX 繪圖代碼和 XAML 界面管理之間進(jìn)行交互操作,使用 DirectWrite 加載字體,使用 WIC 加載圖像,以及將 Direct2D 圖像效果應(yīng)用到圖像。

我們將了解使用 XAML 互操作的 DirectX 雜志應(yīng)用示例的大量代碼并探討構(gòu)成應(yīng)用的不同組件。

雜志示例結(jié)構(gòu)

示例中的文件分為三組:XML、XAML 和 DirectX。XML 組中的文件負(fù)責(zé)表示 XML 文件(容納有關(guān)文章的所有信息)中的每個標(biāo)記。XAML 組中的文件負(fù)責(zé)設(shè)置 XAML 元素并與Virtual Surface Image Source協(xié)作。***,DirectX 組中的文件負(fù)責(zé)像 DirectWrite 自定義字體加載、Direct2D 圖像效果和 WIC 圖像解碼這樣的事情。

名稱 類型
BindableProperty XAML
ContentImageSource XAML
Design XML
Document XML
Element XML
FontFileStream DirectX
FontLoader DirectX
Image XML
ImageFile XML
ImageFrame XML
Layer XML
List XML
Page XML
PageModel XAML
PageRoll XML
Rectangle XML
Resource XML
Story XML
Text XML
TextFrame XML
TreeIterator XML

 

虛擬圖面圖像源

Virtual Surface Image Source (VSIS)是一個 XAML 管理的呈現(xiàn)圖面,當(dāng)你要編寫一個涉及平移和縮放的應(yīng)用時,它將非常有用。此圖面與 DirectX 中的任何其他位圖源相同,除了 XAML 管理 DirectX 和圖像源之間的交互操作這一事實。

當(dāng)你希望在應(yīng)用中使用 VSIS 時,你必須:

  • 確定內(nèi)容的大小。
  • 創(chuàng)建圖像大小的 VSIS
  • 將 DXGI 設(shè)備設(shè)置為 VSIS 上的設(shè)備。
  • 注冊圖像源回調(diào),以便當(dāng)你需要呈現(xiàn)內(nèi)容時收到消息。

下面的代碼顯示如何執(zhí)行這些步驟。

  1. // Measure the content and store its size. 
  2.     Measure(&m_contentSize); 
  3.  
  4.     // Create an image source at the initial pixel size. 
  5.     m_imageSource = ref new VirtualSurfaceImageSource(m_contentSize.cx, m_contentSize.cy); 
  6.  
  7.     ComPtr<IUnknown> unknown(reinterpret_cast<IUnknown*>(m_imageSource)); 
  8.     unknown.As(&m_imageSourceNative); 
  9.  
  10.     auto renderer = m_document->GetRenderer(); 
  11.  
  12.     // Set DXGI device to the image source 
  13.     ComPtr<IDXGIDevice> dxgiDevice; 
  14.     renderer->GetDXGIDevice(&dxgiDevice); 
  15.     m_imageSourceNative->SetDevice(dxgiDevice.Get()); 
  16.  
  17.     // Register image source's update callback so update can be made to it. 
  18.     m_imageSourceNative->RegisterForUpdatesNeeded(this); 

選擇,你有了一個 VSIS 并注冊你的類接收來自虛擬圖面的回調(diào)信息。接下來,你必須實現(xiàn)當(dāng)你需要更新內(nèi)容時 VSIS 調(diào)用的回調(diào)方法。

當(dāng)用戶通過滾動內(nèi)容來操作 VSIS 時,VSIS 將調(diào)用你注冊的類的 UpdatesNeeded 方法。因此,你必須實現(xiàn) UpdatesNeeded 回調(diào)方法。

下面的代碼向你顯示了如何實現(xiàn) UpdatesNeeded 回調(diào)方法和 Draw 幫助程序方法。當(dāng) VSISContentImageSource 類上調(diào)用此回調(diào)方法時,此方法將檢索 VSIS 正在使用 VSISGetUpdateRectCount 方法呈現(xiàn)的更新的矩形。然后,你對此更新的區(qū)域調(diào)用繪制方法。

  1. / This method is called when the framework needs to update region managed by 
  2. // the virtual surface image source. 
  3. HRESULT STDMETHODCALLTYPE ContentImageSource::UpdatesNeeded() 
  4.     HRESULT hr = S_OK; 
  5.  
  6.     try 
  7.     { 
  8.         ULONG drawingBoundsCount = 0; 
  9.  
  10.         DX::ThrowIfFailed( 
  11.             m_imageSourceNative->GetUpdateRectCount(&drawingBoundsCount) 
  12.             ); 
  13.  
  14.         std::unique_ptr<RECT[]> drawingBounds(new RECT[drawingBoundsCount]); 
  15.  
  16.         DX::ThrowIfFailed( 
  17.             m_imageSourceNative->GetUpdateRects(drawingBounds.get(), drawingBoundsCount) 
  18.             ); 
  19.  
  20.         // This code doesn't try to coalesce multiple drawing bounds into one. Although that 
  21.         // extra process  reduces the number of draw calls, it requires the virtual surface 
  22.         // image source to manage non-uniform tile size, which requires it to make extra copy 
  23.         // operations to the compositor. By using the drawing bounds it directly returns, which are 
  24.         //  non-overlapping  tiles of the same size, the compositor can use these tiles directly, 
  25.         // which can greatly reduce the amount of memory needed by the virtual surface image source. 
  26.         // This results in more draw calls, but Direct2D can accommodate them 
  27.         // without significant impact on presentation frame rate. 
  28.         for (ULONG i = 0; i < drawingBoundsCount; ++i) 
  29.         { 
  30.             if (Draw(drawingBounds[i])) 
  31.             { 
  32.                 // Drawing isn't complete. This can happen when the content is still being 
  33.                 // asynchronously loaded. Inform the image source to invalidate the drawing 
  34.                 // bounds so that it calls back to redraw. 
  35.                 DX::ThrowIfFailed( 
  36.                     m_imageSourceNative->Invalidate(drawingBounds[i]) 
  37.                     ); 
  38.             } 
  39.         } 
  40.     } 
  41.     catch (Platform::Exception^ exception) 
  42.     { 
  43.         hr = exception->HResult; 
  44.     } 
  45.  
  46.     return hr; 
  47.  
  48. bool ContentImageSource::Draw(RECT const& drawingBounds) 
  49.     ComPtr<IDXGISurface> dxgiSurface; 
  50.     POINT surfaceOffset = {0}; 
  51.  
  52.     DX::ThrowIfFailed( 
  53.         m_imageSourceNative->BeginDraw( 
  54.             drawingBounds, 
  55.             &dxgiSurface, 
  56.             &surfaceOffset 
  57.             ) 
  58.         ); 
  59.  
  60.     auto renderer = m_document->GetRenderer(); 
  61.  
  62.     ComPtr<ID2D1DeviceContext> d2dDeviceContext; 
  63.     renderer->GetD2DDeviceContext(&d2dDeviceContext); 
  64.  
  65.     ComPtr<ID2D1Bitmap1> bitmap; 
  66.     DX::ThrowIfFailed( 
  67.         d2dDeviceContext->CreateBitmapFromDxgiSurface( 
  68.             dxgiSurface.Get(), 
  69.             nullptr, 
  70.             &bitmap 
  71.             ) 
  72.         ); 
  73.  
  74.     // Begin the drawing batch 
  75.     d2dDeviceContext->BeginDraw(); 
  76.  
  77.     // Scale content design coordinate to the display coordinate, 
  78.     // then translate the drawing to the designated place on the surface. 
  79.     D2D1::Matrix3x2F transform = 
  80.         D2D1::Matrix3x2F::Scale( 
  81.             m_document->DesignToDisplayWidth(1.0f), 
  82.             m_document->DesignToDisplayHeight(1.0f) 
  83.             ) * 
  84.         D2D1::Matrix3x2F::Translation( 
  85.             static_cast<float>(surfaceOffset.x - drawingBounds.left), 
  86.             static_cast<float>(surfaceOffset.y - drawingBounds.top) 
  87.             ); 
  88.  
  89.     // Prepare to draw content. This is the appropriate time for content element 
  90.     // to draw to an intermediate if there is any. It is important for performance 
  91.     // reason that you don't call SetTarget too often. Preparing the intermediates 
  92.     // upfront reduces the number of times the render target switches back and forth. 
  93.     bool needRedraw = m_content->PrepareToDraw( 
  94.         m_document, 
  95.         transform 
  96.         ); 
  97.  
  98.     if (!needRedraw) 
  99.     { 
  100.         // Set the render target to surface given by the framework 
  101.         d2dDeviceContext->SetTarget(bitmap.Get()); 
  102.  
  103.         d2dDeviceContext->SetTransform(D2D1::IdentityMatrix()); 
  104.  
  105.         // Constrain the drawing to the designated portion of the surface 
  106.         d2dDeviceContext->PushAxisAlignedClip( 
  107.             D2D1::RectF( 
  108.                 static_cast<float>(surfaceOffset.x), 
  109.                 static_cast<float>(surfaceOffset.y), 
  110.                 static_cast<float>(surfaceOffset.x + (drawingBounds.right - drawingBounds.left)), 
  111.                 static_cast<float>(surfaceOffset.y + (drawingBounds.bottom - drawingBounds.top)) 
  112.                 ), 
  113.             D2D1_ANTIALIAS_MODE_ALIASED 
  114.             ); 
  115.  
  116.         // The Clear call must follow the PushAxisAlignedClip call. 
  117.         // Placing the Clear call before the clip is set violates the contract of the 
  118.         // virtual surface image source in that the app draws outside the 
  119.         // designated portion of the surface the image source hands over to it. This 
  120.         // violation won't actually cause the content to spill outside the designated 
  121.         // area because the image source will safeguard it. But this extra protection 
  122.         // has a runtime cost associated with it, and in some drivers this cost can be 
  123.         // very expensive. So the best performance strategy here is to never create a 
  124.         // situation where this protection is required. Not drawing outside the appropriate 
  125.         // clip does that the right way. 
  126.         d2dDeviceContext->Clear(D2D1::ColorF(0, 0)); 
  127.  
  128.         // Draw the content 
  129.         needRedraw = m_content->Draw( 
  130.             m_document, 
  131.             transform 
  132.             ); 
  133.  
  134.         d2dDeviceContext->PopAxisAlignedClip(); 
  135.  
  136.         d2dDeviceContext->SetTarget(nullptr); 
  137.     } 
  138.  
  139.     // End the drawing 
  140.     DX::ThrowIfFailed( 
  141.         d2dDeviceContext->EndDraw() 
  142.         ); 
  143.  
  144.     // Submit the completed drawing to the framework 
  145.     DX::ThrowIfFailed( 
  146.         m_imageSourceNative->EndDraw() 
  147.         ); 
  148.  
  149.     return needRedraw; 

#p#

實現(xiàn)回調(diào)后,你的應(yīng)用現(xiàn)在將從 VSIS 接收有關(guān)你需要繪制的區(qū)域的信息。你的 draw 函數(shù)只需要獲取此矩形,并繪制到 VSIS 的右側(cè)區(qū)域中。通過實現(xiàn)這兩個回調(diào),并向 VSIS 注冊類,應(yīng)用便可以在用戶操作內(nèi)容時呈現(xiàn)到虛擬圖面并更新必要的區(qū)域,以顯示更多圖面。

使用 XML 加載內(nèi)容和綁定數(shù)據(jù)

我們的應(yīng)用顯示在雜志中的信息都存儲在 Sample.story 文件中。此文件是一個 XML 文檔,它包含有關(guān)文章內(nèi)容、標(biāo)題、字體、背景圖像和其他屬性的信息。 應(yīng)用需要編入摘要的每一部分重要信息都有一個標(biāo)記。通過使用標(biāo)記,你可以輕松地展開文章,從該標(biāo)記的信息中創(chuàng)建對象,以及將該數(shù)據(jù)綁定到你的應(yīng)用的 XAML 中。

因為 .story 文件中的信息采用自定義的 XML 架構(gòu),所以 TreeIterator.h 中的類幫助分析此 XML 數(shù)據(jù)并將其置于應(yīng)用的專用類中。

下面是應(yīng)用使用的 .story 文件中包含的信息示例。

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <story> 
  3.     <resource> 
  4.         <image name="grasshopper-image" file="grasshopper.jpg"/> 
  5.         <image name="butterfly-image" file="butterfly.jpg"/> 
  6.         <text name="section" font-family="Arial" font-stretch="2" font-size="22">A BUG'S LIFE</text> 
  7.         <text name="grasshopper-title" font-family="Gill Sans" font-stretch="3" font-weight="700" font-size="70">GRASSHOPPER</text> 
  8.         <text name="grasshopper-quote" font-family="Pericles" font-size="18">a slender plant-eating flying and jumping insect that produces a buzzing sound by rubbing its back legs against its forewings</text> 
  9.         <text name="grasshopper-body" font-family="Kootenay" font-size="16"><bold>LOREM</bold> ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. 
  10. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem.</text> 

如 XML 代碼段所示,信息的標(biāo)記直接對應(yīng)于應(yīng)用中的某些 XML 類。當(dāng)?shù)鞣治?XML 文件時,將為每個標(biāo)記創(chuàng)建一個相同名稱的類,在其中存儲標(biāo)記中的信息。

在我們將 XML 文件中的所有信息都存儲到應(yīng)用后,你將該數(shù)據(jù)綁定到 UI 上的元素。此數(shù)據(jù)綁定存在于兩個位置,頁面的 XAML 標(biāo)記中及 XAML 標(biāo)記頁面隨附的 cpp 文件中。在此示例中,它存在于 MainPage.xamlMainPage.cpp 中。

在 XAML 標(biāo)記中創(chuàng)建 FlipViewDataTemplateScrollViewer 類的實例。然后,將該信息綁定到那些 XAML 標(biāo)記項。下面是這些元素的 XAML 標(biāo)記代碼。

  1. <FlipView x:Name="FlipView" ManipulationMode="TranslateInertia"> 
  2.         <FlipView.ItemTemplate> 
  3.             <DataTemplate> 
  4.                 <ScrollViewer ZoomMode="Disabled" VerticalScrollMode="Enabled" IsVerticalRailEnabled="True"> 
  5.                     <ScrollViewer.Background> 
  6.                         <ImageBrush ImageSource="{Binding Background}"/> 
  7.                     </ScrollViewer.Background> 
  8.                     <Image  
  9.                         Source="{Binding Content}"  
  10.                         Width="{Binding ContentWidth}"  
  11.                         Height="{Binding ContentHeight}"  
  12.                         HorizontalAlignment="Left" 
  13.                         /> 
  14.                 </ScrollViewer> 
  15.             </DataTemplate> 
  16.         </FlipView.ItemTemplate> 
  17.     </FlipView> 

此處的代碼顯示,背景和圖像全都具有對應(yīng)于 XML 源中數(shù)據(jù)的數(shù)據(jù)綁定。現(xiàn)在,你需要使用你具有的信息填充這些綁定。你將代碼放置在相同名稱的 cpp 文件中。下面是 MainPage.cpp 中幫助進(jìn)行數(shù)據(jù)綁定的代碼。

  1. void MainPage::DocumentLoaded(_In_ Document^ document) 
  2.     // Parse the document into an element tree. 
  3.     document->Parse(); 
  4.  
  5.     auto contentRoot = document->GetContentRoot(); 
  6.  
  7.     if (contentRoot != nullptr) 
  8.     { 
  9.         // Create a collection of content element to bind to the view 
  10.         auto items = ref new Platform::Collections::Vector<Platform::Object^>(); 
  11.  
  12.         auto pageContent = contentRoot->GetFirstChild(); 
  13.  
  14.         while (pageContent != nullptr) 
  15.         { 
  16.             items->Append(ref new PageModel(pageContent, document)); 
  17.  
  18.             pageContent = pageContent->GetNextSibling(); 
  19.         } 
  20.  
  21.         FlipView->ItemsSource = items; 
  22.  
  23.         // Load the saved document state if any 
  24.         LoadState(ApplicationData::Current->LocalSettings->Values); 
  25.  
  26.         m_document = document; 
  27.     } 

此處的代碼分析 XML 文檔,然后創(chuàng)建內(nèi)容元素的矢量,以便將其綁定到 UI 中的 XAML 元素。

自定義字體加載

要在此 DirectX 應(yīng)用中使用自定義字體,你必須在 DirectWrite 中實現(xiàn)異步字體加載程序和集合。在 DirectX 應(yīng)用中,如果你希望提供一個要在文本元素上使用的自定義字體,你需要使用 DirectWrite 獲取未安裝在用戶系統(tǒng)上的新字體。在示例中,可在 FontFileStreamFontLoader 類中找到加載和提供這些新字體的代碼。

FontFileStream 類是 IDWriteFontFileStream 接口的實現(xiàn),它接受實際字體文件并將其加載到應(yīng)用可以編入摘要的表單中。這涉及到讀取文件片段、釋放文件片段、獲取文件大小及獲取***編輯時間的處理方法。

下面是用于讀取和釋放字體文件片段的代碼。

  1. HRESULT STDMETHODCALLTYPE FontFileStream::ReadFileFragment( 
  2.     _Outptr_result_bytebuffer_(fragmentSize) void const** fragmentStart, 
  3.     UINT64 fileOffset, 
  4.     UINT64 fragmentSize, 
  5.     _Out_ void** fragmentContext 
  6.     ) 
  7.     // The loader is responsible for doing a bounds check. 
  8.     if (    fileOffset <= m_data->Length 
  9.         &&  fragmentSize + fileOffset <= m_data->Length 
  10.         ) 
  11.     { 
  12.         *fragmentStart = m_data->Data + static_cast<ULONG>(fileOffset); 
  13.         *fragmentContext = nullptr; 
  14.         return S_OK; 
  15.     } 
  16.     else 
  17.     { 
  18.         *fragmentStart = nullptr; 
  19.         *fragmentContext = nullptr; 
  20.         return E_FAIL; 
  21.     } 
  22.  
  23. void STDMETHODCALLTYPE FontFileStream::ReleaseFileFragment( 
  24.     _In_ void* fragmentContext 
  25.     ) 

#p#

下面是用于檢索文件大小和***編輯時間的代碼。

  1. HRESULT STDMETHODCALLTYPE FontFileStream::GetFileSize( 
  2.     _Out_ UINT64* fileSize 
  3.     ) 
  4.     *fileSize = m_data->Length; 
  5.     return S_OK; 
  6.  
  7. HRESULT STDMETHODCALLTYPE FontFileStream::GetLastWriteTime( 
  8.     _Out_ UINT64* lastWriteTime 
  9.     ) 
  10.     // The concept of last write time does not apply to this loader. 
  11.     *lastWriteTime = 0; 
  12.     return E_NOTIMPL; 

在所有片段均已到位并且你可以訪問字體文件中的信息后,你必須編寫允許你從文件流中構(gòu)造自定義字體集合和字體對象的代碼。可以在 FontLoader.cpp 文件中找到此代碼。

首先,你需要一個函數(shù)用于加載和枚舉你要使用的字體。以下代碼用于 LoadAsync 函數(shù),該函數(shù)查找雜志示例中的字體目錄,并枚舉該目錄中的 .ttf 字體文件列表。

  1. task<void> FontLoader::LoadAsync() 
  2.     // Locate the "fonts" subfolder within the document folder 
  3.     return task<void>([this]() 
  4.     { 
  5.         task<StorageFolder^>(m_location->GetFolderAsync("fonts")).then([=](StorageFolder^ folder) 
  6.         { 
  7.             // Enumerate a list of .TTF files in the storage location 
  8.             auto filters = ref new Platform::Collections::Vector<Platform::String^>(); 
  9.             filters->Append(".ttf"); 
  10.  
  11.             auto queryOptions = ref new QueryOptions(CommonFileQuery::DefaultQuery, filters); 
  12.             auto queryResult = folder->CreateFileQueryWithOptions(queryOptions); 
  13.  
  14.             return queryResult->GetFilesAsync(); 
  15.  
  16.         }).then([=](IVectorView<StorageFile^>^ files) 
  17.         { 
  18.             m_fontFileCount = files->Size; 
  19.  
  20.             std::vector<task<IBuffer^>> tasks; 
  21.  
  22.             for (uint32 i = 0; i < m_fontFileCount; ++i) 
  23.             { 
  24.                 auto file = dynamic_cast<StorageFile^>(files->GetAt(i)); 
  25.  
  26.                 tasks.push_back(task<IBuffer^>(FileIO::ReadBufferAsync(file))); 
  27.             } 
  28.  
  29.             return when_all(tasks.begin(), tasks.end()); 
  30.  
  31.         }).then([=](std::vector<IBuffer^> buffers) 
  32.         { 
  33.             for each (IBuffer^ buffer in buffers) 
  34.             { 
  35.                 auto fileData = ref new Platform::Array<byte>(buffer->Length); 
  36.                 DataReader::FromBuffer(buffer)->ReadBytes(fileData); 
  37.  
  38.                 ComPtr<FontFileStream> fontFileStream(new FontFileStream(fileData)); 
  39.                 m_fontFileStreams.push_back(fontFileStream); 
  40.             } 
  41.  
  42.         }).wait(); 
  43.     }); 

現(xiàn)在,編寫另一個方法,它采用在 DirectWrite 創(chuàng)建自定義字體集合時傳入的字體集合項。此方法將采用此值并返回字體文件枚舉器。

  1. HRESULT STDMETHODCALLTYPE FontLoader::CreateEnumeratorFromKey( 
  2.     _In_ IDWriteFactory* factory, 
  3.     _In_reads_bytes_(fontCollectionKeySize) void const* fontCollectionKey, 
  4.     uint32 fontCollectionKeySize, 
  5.     _Outptr_ IDWriteFontFileEnumerator** fontFileEnumerator 
  6.     ) 
  7.     *fontFileEnumerator = ComPtr<IDWriteFontFileEnumerator>(this).Detach(); 
  8.     return S_OK; 

此方法接受相同的集合項并返回字體文件流。

  1. HRESULT STDMETHODCALLTYPE FontLoader::CreateStreamFromKey( 
  2.     _In_reads_bytes_(fontFileReferenceKeySize) void const* fontFileReferenceKey, 
  3.     uint32 fontFileReferenceKeySize, 
  4.     _Outptr_ IDWriteFontFileStream** fontFileStream 
  5.     ) 
  6.     if (fontFileReferenceKeySize != sizeof(size_t)) 
  7.     { 
  8.         return E_INVALIDARG; 
  9.     } 
  10.  
  11.     size_t fontFileStreamIndex = *(static_cast<size_t const*>(fontFileReferenceKey)); 
  12.  
  13.     *fontFileStream = ComPtr<IDWriteFontFileStream>(m_fontFileStreams.at(fontFileStreamIndex).Get()).Detach(); 
  14.  
  15.     return S_OK; 

接下來的 2 個方法是幫助程序方法。 ***個函數(shù)移到文件流中的下一個字體文件,另一個函數(shù)用作當(dāng)前字體文件的簡單 getter。下面是這 2 種方法的代碼。

  1. HRESULT STDMETHODCALLTYPE FontLoader::MoveNext(OUT BOOL* hasCurrentFile) 
  2.     *hasCurrentFile = FALSE; 
  3.  
  4.     if (m_fontFileStreamIndex < m_fontFileCount) 
  5.     { 
  6.         DX::ThrowIfFailed( 
  7.             m_dwriteFactory->CreateCustomFontFileReference( 
  8.                 &m_fontFileStreamIndex, 
  9.                 sizeof(size_t), 
  10.                 this
  11.                 &m_currentFontFile 
  12.                 ) 
  13.             ); 
  14.  
  15.         *hasCurrentFile = TRUE; 
  16.         ++m_fontFileStreamIndex; 
  17.     } 
  18.  
  19.     return S_OK; 
  20.  
  21. HRESULT STDMETHODCALLTYPE FontLoader::GetCurrentFontFile(OUT IDWriteFontFile** currentFontFile) 
  22.     *currentFontFile = ComPtr<IDWriteFontFile>(m_currentFontFile.Get()).Detach(); 
  23.     return S_OK; 

我們的代碼完成后,你現(xiàn)在已擁有一個異步處理應(yīng)用的正常字體文件加載程序。這 2 個類一起用于枚舉系統(tǒng)上的文件,將它們加載到字體文件流中,并使用你可以使用的這些字體創(chuàng)建一個自定義字體集合。

使用 VSIS 的***實踐

當(dāng)你希望執(zhí)行 DirectX 和 XAML 互操作時,Windows 8 支持Surface Image SourceVirtual Surface Image Source,但是具體使用哪一個取決于你希望執(zhí)行什么操作。

有 3 個主要方案,每一個都有一個 XAML 互操作選項。

  • 繪制元素(如紋理)作為應(yīng)用中的位圖。
  • 繪制大于屏幕的位圖,因此需要進(jìn)行平移。
  • 改進(jìn)觸摸操作的性能。

如果你需要管理靜態(tài)圖像或偶然更新 SIS 的內(nèi)容,則Surface Image Source是一個好的選擇。當(dāng) SIS 有用時的一個良好示例是,如果你希望將位圖繪制為 XAML UI 元素。此元素可能需要進(jìn)行更新以顯示不同的信息,但是大部分是靜態(tài)的。SIS 能很好地發(fā)揮作用,因為你的應(yīng)用對 SIS 所做的更新與 XAML UI 線程同步,因此在它需要像應(yīng)用中的 UI 一樣高性能的方案中運行得***。

但是如果你需要一個需要直接操作(滾動或平移)的較大位圖或 DirectX 內(nèi)容區(qū)域,則使用 VSIS。如果你要顯示的信息不能容納到屏幕或元素上,則 VSIS 會很有用。一個使用 VSIS 的良好示例是具有滾動文本的閱讀應(yīng)用,或者需要平移和縮放以探索地圖的地圖應(yīng)用。

如果這些方案中沒有一個匹配你的應(yīng)用使用情況,則 VSISSIS 可能不適合你的應(yīng)用。尤其,如果性能對你的應(yīng)用來說很重要,則 XAML 中的 SwapChainBackgroundPanel 元素可能***。有關(guān)詳細(xì)信息,請參閱 Windows.UI::Xaml::Controls::SwapChainBackgroundPanel

原文鏈接:http://msdn.microsoft.com/zh-cn/library/windows/apps/jj552955.aspx

責(zé)任編輯:陳四芳 來源: microsoft.com
相關(guān)推薦

2013-09-02 16:59:34

JavaScriptHTML

2013-09-03 10:40:45

JavaScriptWindows

2013-09-02 16:52:31

Windows 8.1

2011-09-15 18:43:00

UbuntuchmPDF

2014-12-03 10:46:15

iReader

2017-04-11 13:31:40

閱讀器開源RSS

2009-05-05 09:00:48

RSS瀏覽器

2024-05-16 13:44:18

2011-09-09 10:19:13

2020-03-13 19:26:38

Linux電子書閱讀器桌面應(yīng)用

2014-12-17 15:23:03

Android網(wǎng)絡(luò)閱讀器源碼

2015-12-03 10:04:36

Ncurses工具LNAV

2023-09-29 11:47:23

2022-06-02 14:01:54

屏幕閱讀器NVDAWindows

2023-03-23 13:47:00

LinuxEPUB閱讀器

2009-08-27 09:19:51

RSS閱讀器Web 1.0

2016-12-20 09:29:11

AlduinLinuxRSS

2021-05-21 05:26:02

谷歌Chrome 瀏覽器

2009-07-29 09:35:07

谷歌離職

2021-07-29 15:57:11

任意代碼漏洞攻擊
點贊
收藏

51CTO技術(shù)棧公眾號

精品视频在线一区二区| 亚洲永久精品一区| 亚洲小说图片| 欧美日韩成人激情| 成年丰满熟妇午夜免费视频 | 久久免费高清| 久久天天躁日日躁| 国产精品伦子伦| 国产人妖一区| 欧美性猛交xxxx黑人| 影音先锋欧美资源| 青青色在线视频| 国模无码大尺度一区二区三区| 午夜精品一区二区三区在线视| 魔女鞋交玉足榨精调教| 国产精品va视频| 色婷婷综合久久久中文字幕| 欧美在线观看黄| 国产高清在线| 99精品视频中文字幕| 91九色综合久久| 成人免费视频国产免费| 91久久夜色精品国产九色| 伊人亚洲福利一区二区三区| 日韩综合第一页| 精品国产伦一区二区三区观看说明| 欧美性极品xxxx娇小| 成人午夜免费在线视频| 五月婷婷在线视频| 国产人伦精品一区二区| 精品国产乱码一区二区三区四区 | 欧美成人a∨高清免费观看| 18岁视频在线观看| aa视频在线观看| 一区二区三区四区不卡在线| 色撸撸在线观看| 成人精品福利| 国产亚洲成av人在线观看导航 | 亚洲高清免费观看高清完整版在线观看 | 久久久久国产精品人| 好吊妞www.84com只有这里才有精品 | 久久看片网站| 欧亚精品在线观看| 狠狠躁夜夜躁人人爽天天高潮| 午夜精品偷拍| 欧美精品在线视频观看| 欧美视频一区二区在线| 欧洲激情视频| 一个人www欧美| 扒开jk护士狂揉免费| 日韩人体视频| 国产视频自拍一区| 一区二区免费在线观看视频| caoporn成人| 亚洲大尺度美女在线| 无码人妻精品一区二区三区99不卡| 视频精品一区| 精品国产一区二区精华| 国产xxxxxxxxx| 同性恋视频一区| 亚洲色图15p| 国产又黄又粗视频| 久久久久久免费视频| 久久精视频免费在线久久完整在线看| 美女av免费看| 亚洲一区二区三区| 欧美精品激情在线观看| 国产又大又黄又粗| 男女激情视频一区| 成人免费xxxxx在线观看| 国产按摩一区二区三区| 成人久久18免费网站麻豆| 久久亚洲一区二区| 在线视频1区2区| 亚洲激情综合网| a级黄色一级片| 99只有精品| 日韩欧美一二区| 成年人网站免费看| 日韩综合在线| 久久久久久国产精品三级玉女聊斋| 日本在线观看中文字幕| 日韩精品一区第一页| 成人激情视频网| 欧美一级性视频| 国产欧美日韩精品在线| 男女爱爱视频网站| 理论片午夜视频在线观看| 欧美三级中文字幕| 亚洲av熟女高潮一区二区| 国产aⅴ精品一区二区三区久久| 主播福利视频一区| 国产在线视频在线观看| 老司机精品福利视频| 5566av亚洲| 女人偷人在线视频| 亚洲精品乱码久久久久久黑人| 日韩av资源在线| 日韩不卡在线视频| 国产午夜精品视频免费不卡69堂| 欧美成人三级在线观看| 日韩精品亚洲一区二区三区免费| 成人欧美一区二区| av资源在线观看免费高清| 亚洲国产精品久久久久秋霞影院| 天天色综合社区| 国内毛片久久| 久热精品视频在线观看一区| 伦av综合一区| 成人在线一区二区三区| 欧美爱爱视频网站| 少妇一区视频| 亚洲韩国欧洲国产日产av| 免费精品在线视频| 久久久夜精品| 久久久久久久久久久久久久一区 | 国产精品成人va在线观看| 亚洲精品人妻无码| 日韩理论片在线| 最新天堂中文在线| 九九亚洲视频| 午夜精品美女自拍福到在线| www.国产欧美| 中文字幕日韩精品一区| 国产视频在线视频| 天堂99x99es久久精品免费| 色在人av网站天堂精品| ,亚洲人成毛片在线播放| 国产日韩成人精品| av动漫在线看| 好吊妞视频这里有精品| 九九精品在线观看| 99热这里只有精| 亚洲图片激情小说| 五月天丁香花婷婷| 99精品在线| 国产精品自在线| www.亚洲.com| 欧美亚洲禁片免费| 色噜噜噜噜噜噜| 麻豆一区二区在线| 欧美日韩视频免费在线观看| 黄色日韩网站| www.日本久久久久com.| 91成人国产综合久久精品| 国产精品女人毛片| 亚洲色图 在线视频| 成人一区二区| 国产免费久久av| 日韩黄色影院| 678五月天丁香亚洲综合网| 日本黄色录像视频| 国产一区二区三区免费观看| 免费在线精品视频| 亚洲视频一起| 亚洲2020天天堂在线观看| 污视频在线免费观看| 色综合久久久久综合| 久久久久久国产免费a片| 久久超碰97中文字幕| 日本一级淫片演员| 91午夜精品| 欧美综合一区第一页| av大全在线免费看| 欧美一区二区三区白人| 亚洲精品午夜久久久久久久| 91在线观看免费视频| 久久综合色视频| 欧美日韩国产传媒| 91视频九色网站| 国产精品高颜值在线观看| 亚洲欧美www| 91片黄在线观看喷潮| 亚洲午夜激情av| 中文字幕国产专区| 国产一区久久久| 欧美人成在线观看| 欧美极品在线观看| 成人国产精品一区二区| av在线资源| 伊人伊成久久人综合网站| 国产乱码一区二区| 精品福利樱桃av导航| 亚洲不卡的av| 粉嫩一区二区三区性色av| 国产精品亚洲αv天堂无码| 久久一区91| 国产无套精品一区二区| 国产亚洲精品精品国产亚洲综合| 欧美激情中文字幕乱码免费| 伦理片一区二区三区| 5858s免费视频成人| 久久夜色精品亚洲| 中文字幕一区免费在线观看| 天堂久久久久久| 国产在线观看免费一区| 欧美一级在线看| 中文在线播放一区二区 | 国产无套粉嫩白浆在线2022年| 欧美日韩在线观看一区二区| 亚洲精品午夜久久久久久久| 亚洲欧洲成人av每日更新| 最近中文字幕无免费| 国内外成人在线| 北条麻妃av高潮尖叫在线观看| 欧美精选在线| 91免费网站视频| 欧美伦理影院| 欧美日韩精品免费观看| 亚洲日本一区二区三区在线| 成人h视频在线观看播放| 亚洲欧洲高清| 国内久久久精品| av超碰免费在线| 日日骚久久av| 久久精品蜜桃| 亚洲精品久久久一区二区三区| 国产福利免费视频| 欧美日韩色一区| 亚洲 欧美 日韩 在线| 婷婷六月综合亚洲| 精品在线视频免费| 亚洲青青青在线视频| 蜜桃av.com| 国产精品久久国产精麻豆99网站| 久久精品国产亚洲AV熟女| 91网上在线视频| 中文在线观看免费视频| 丁香激情综合国产| 中文字幕一二三区| 国产剧情av麻豆香蕉精品| 欧美特黄aaa| 麻豆91精品91久久久的内涵| 国产aaaaa毛片| 日本欧美一区二区在线观看| 日韩亚洲在线视频| 久久久久国产精品一区二区| 自慰无码一区二区三区| 99精品国产一区二区青青牛奶| 成人免费在线网| 亚洲第一网站| 国产h视频在线播放| 国产精品日韩久久久| 黄色免费视频大全| 丝袜美腿亚洲综合| av污在线观看| 狠狠色综合日日| 日韩 国产 一区| 国产精品亚洲午夜一区二区三区 | 6080国产精品| 国产精品自拍在线| 97中文字幕在线观看| av一区二区三区| www.中文字幕av| 国产精品丝袜在线| 侵犯稚嫩小箩莉h文系列小说| 亚洲摸摸操操av| 久久影院一区二区| 欧美日韩亚洲91| 懂色av蜜臀av粉嫩av分享吧最新章节| 色吊一区二区三区| 亚洲一区中文字幕在线| 这里是久久伊人| 人成网站在线观看| 亚洲精品在线91| 三区四区在线视频| 久久久久久久久久久av| 美女av在线免费看| 国产精品久久久久久婷婷天堂| 国产精品原创视频| 99国产高清| 亚洲警察之高压线| 一区二区免费在线视频| 欧美日一区二区三区在线观看国产免| 好吊妞无缓冲视频观看| 日韩国产欧美三级| 日本一本在线视频| 91在线视频免费观看| 91制片厂在线| 亚洲图片有声小说| 天堂av免费在线观看| 91精品国产91综合久久蜜臀| 天天操天天射天天舔| 中文字幕日韩欧美精品在线观看| 欧美wwww| 国产精品嫩草影院一区二区| 一本色道69色精品综合久久| 欧美日韩三区四区| 欧美另类视频| 在线观看免费黄网站| 成人国产精品免费网站| 成人做爰视频www| 亚洲电影免费观看高清完整版在线观看 | 女人高潮被爽到呻吟在线观看| 国产精品一区二区三区成人| 欧美午夜网站| 日韩在线电影一区| 亚洲韩日在线| av中文字幕网址| 26uuu精品一区二区三区四区在线| 日本成人精品视频| 岛国av午夜精品| 国产成人久久精品77777综合| 亚洲免费高清视频| 丰满诱人av在线播放| 国产精品青草久久久久福利99| 第一区第二区在线| 自拍偷拍一区二区三区| 老司机免费视频久久 | 久久久噜噜噜久久中文字幕色伊伊 | 大胆日韩av| www国产精品内射老熟女| 国产老女人精品毛片久久| 久久久国产一级片| 色婷婷av一区二区三区之一色屋| 亚洲av无码国产精品永久一区 | 全部av―极品视觉盛宴亚洲| 国产精品福利导航| 亚洲黄色录像片| 国产又粗又大又爽| 亚洲日韩欧美视频| 亚洲深夜视频| 极品校花啪啪激情久久| 欧美人成在线| 中文字幕人妻无码系列第三区| 国产精品天美传媒沈樵| 久久国产香蕉视频| 亚洲人成在线观看网站高清| 在线观看欧美日韩电影| 精品久久久久久亚洲| 精品成人国产| 亚洲色图欧美另类| 亚洲自拍偷拍综合| 亚洲AV无码成人片在线观看 | 欧美freesex| 蜜桃欧美视频| 亚洲免费中文| 亚洲第一香蕉网| 一本色道a无线码一区v| 亚洲av电影一区| 欧美一区二区色| 亚洲ab电影| 无码日韩人妻精品久久蜜桃| 国产亚洲女人久久久久毛片| 国产嫩bbwbbw高潮| 亚洲欧美中文日韩在线v日本| 亚州一区二区三区| 亚洲国产精品一区二区第四页av| 日韩不卡免费视频| 美国精品一区二区| 欧美一级理论性理论a| 伊人在我在线看导航| 成人免费视频网站| 日韩天堂av| 免费人成又黄又爽又色| 欧美色爱综合网| 国产黄色小视频在线| 国产v亚洲v天堂无码| 国产精品久久久久久模特| 中国美女乱淫免费看视频| 日本精品视频一区二区三区| 午夜激情视频在线| 999精品在线观看| 99精品国产一区二区青青牛奶 | 成人欧美一区二区三区小说| 国产色视频在线| 欧美精品videosex性欧美| 欧美一区自拍| wwwwxxxx日韩| 一区二区三区精品视频在线| 色欲av伊人久久大香线蕉影院| 秋霞av国产精品一区| 欧美a级片视频| 动漫av在线免费观看| 一本到不卡免费一区二区| 免费观看久久久久| 国产一区二区久久久| 日韩av中文字幕一区二区| 成人免费毛片xxx| 亚洲国产免费av| 日韩深夜福利网站| 草草视频在线免费观看| 中文字幕av不卡| 色呦呦中文字幕| 成人av在线亚洲| 香蕉久久国产| 五月天激情丁香| 亚洲男人天堂视频| 日韩精品免费视频一区二区三区| 波多野结衣乳巨码无在线| 亚洲日本护士毛茸茸| 久久久久久女乱国产| 97在线电影| 蜜臀精品一区二区三区在线观看| 国产亚洲精品久久久久久无几年桃| 亚洲网站在线播放| 国产精品久久久久av蜜臀| 在线看的黄色网址| 一本一本久久a久久精品综合麻豆| 182tv在线播放|